1. 程式人生 > >開發中遇到的那些意想不到的bug

開發中遇到的那些意想不到的bug

1、selector.xml與圖片重名。

java.lang.StackOverflowError
	at android.graphics.Bitmap.getScaledWidth(Bitmap.java:1138)
	at android.graphics.drawable.BitmapDrawable.computeBitmapSize(BitmapDrawable.java:189)
	at android.graphics.drawable.BitmapDrawable.setBitmap(BitmapDrawable.java:197)
	at android.graphics.drawable.BitmapDrawable.<init>(BitmapDrawable.java:700)
	at android.graphics.drawable.BitmapDrawable.<init>(BitmapDrawable.java:62)
	at android.graphics.drawable.BitmapDrawable$BitmapState.newDrawable(BitmapDrawable.java:684)
	at android.content.res.Resources.getCachedDrawable(Resources.java:2251)
	at android.content.res.Resources.loadDrawable(Resources.java:2112)
	at com.huawei.android.content.res.ResourcesEx.loadDrawable(ResourcesEx.java:640)
	at android.content.res.Resources.getDrawable(Resources.java:747)
	at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:176)
	at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
	at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
	at android.content.res.Resources.loadDrawable(Resources.java:2156)
	at com.huawei.android.content.res.ResourcesEx.loadDrawable(ResourcesEx.java:640)
	at android.content.res.Resources.getDrawable(Resources.java:747)
	at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:176)
	at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
	at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
	at android.content.res.Resources.loadDrawable(Resources.java:2156)
	at com.huawei.android.content.res.ResourcesEx.loadDrawable(ResourcesEx.java:640)
	at android.content.res.Resources.getDrawable(Resources.java:747)
	at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:176)
	at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
	at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
	at android.content.res.Resources.loadDrawable(Resources.java:2156)
	at com.huawei.android.content.res.ResourcesEx.loadDrawable(ResourcesEx.java:640)
	at android.content.res.Resources.getDrawable(Resources.java:747)
	at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:176)
	at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
	at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
	at android.content.res.Resources.loadDrawable(Resources.java:2156)

有次遇到了這個問題。看到日誌的時候一臉懵逼,而且bug是出現在一臺很奇怪的裝置中,正常裝置沒有問題。

後來我們分析發現,下面的日誌是重複的,這裡棧溢位,其實是因為迴圈載入了bitmap。

後來我們發現,是drawable裡的xml和圖片檔案重名了。在作為selector的xml中,呼叫了圖片檔案,然後因為我們專案中只支援 xh和xxh的drawable,因此,在dpi低的裝置中會導致selector中的呼叫無法匹配到圖片檔案,然後匹配到了 drawable中的xml本身,然後就進入了迴圈匹配,最終導致棧溢位。

2、SharePreference 改名與變數型別改變的版本更替出錯

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.inpor.fastmeetingcloud/com.inpor.fastmeetingcloud.activity.MeetingActivity}: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2504)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2576)
at android.app.ActivityThread.access$1000(ActivityThread.java:163)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1461)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:159)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:975)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:273)
at com.inpor.manager.config.ConfigService.LoadConfig(ConfigService.java:25)
at com.inpor.manager.model.CameraDeviceController.getVideoParam(CameraDeviceController.java:402)
at com.inpor.manager.model.CameraDeviceController.openCamera(CameraDeviceController.java:255)
at com.inpor.fastmeetingcloud.presenter.VideoController.<init>(VideoController.java:64)
at com.inpor.fastmeetingcloud.activity.MeetingActivity.initViews(MeetingActivity.java:240)
at com.inpor.fastmeetingcloud.activity.MeetingActivity.onCreate(MeetingActivity.java:198)
at android.app.Activity.performCreate(Activity.java:6163)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2457)
... 10 more
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:273)
at com.inpor.manager.config.ConfigService.LoadConfig(ConfigService.java:25)
at com.inpor.manager.model.CameraDeviceController.getVideoParam(CameraDeviceController.java:402)
at com.inpor.manager.model.CameraDeviceController.openCamera(CameraDeviceController.java:255)
at com.inpor.fastmeetingcloud.presenter.VideoController.<init>(VideoController.java:64)
at com.inpor.fastmeetingcloud.activity.MeetingActivity.initViews(MeetingActivity.java:240)
at com.inpor.fastmeetingcloud.activity.MeetingActivity.onCreate(MeetingActivity.java:198)
at android.app.Activity.performCreate(Activity.java:6163)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2457)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2576)
at android.app.ActivityThread.access$1000(ActivityThread.java:163)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1461)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:159)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:975)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

新版本上線後,有一個崩潰一天崩了一百多次。我們都很奇怪,明明在SharePreference中這個變數是long,怎麼會出錯呢?

原來,發生了一件很巧合的事情。

在一個比較久遠的版本1中 儲存引數的 SharePreference 被起名A, 裡面有一個 int的引數被命名為 a。後來因為int位數不夠用,將a 從 int 變為了 long,同時,為了防止獲取失敗, SharePreference 被改名為 B,這個改變一直被延續到 上個版本2。在此次釋出的新版本3中,因為又有東西被修改了,因此按照慣例,我們將SharePreference改名。但是好巧不巧,我們為B改的新名字,就是A。因此,從版本1就開始使用,並且一直是通過覆蓋安裝來進行版本升級的使用者,就會一直儲存著版本1的SharePreference,其引數a仍然是int,導致在版本3中因為名字改成了A,又讀取了版本1中保留的資料,導致讀取失敗。