開發中遇到的那些意想不到的bug
阿新 • • 發佈:2019-01-27
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中保留的資料,導致讀取失敗。