Android常见bug

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011386173/article/details/54630886

1、

[Bug的log信息]

ActivityManager: Killing15635:com.android.music/u0a41 (adj 0): depends on providercom.android.providers.media/.MediaProvider in dying procandroid.process.media 

[原因分析]

存在没有关闭的cursor

[解决方案]

排查代码中的cursor使用,关闭未关闭的cursor

2、

[Bug的log信息]

ProcessKiller :Process com.android.gallery3d (2439) has open file/storage/emulated/0/Android/data/com.android.gallery3d/cache/bookmark.idx 

[原因分析]

进程gallery3d因文件句柄未关闭,被重启

[解决方案]

关闭文件句柄或者捕获异常,处理没有创建成功的文件

3、

[Bug的log信息]

java.lang.NullPointerException:Attempt to invoke virtual method "xxx" on a null object reference at ......

[原因分析]

空指针异常,调用某方法的对象为空

[解决方案]

添加空指针防护(对对象进行判空),或者根据逻辑需要新建对象

4、

[Bug的log信息]

signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'art/runtime/indirect_reference_table.cc:115] JNI ERROR (app bug): local reference table overflow (max=512)'

[原因分析]

向JNI传递大量的数据,或者创建了大量对象,若不及时释放,则会造成上述错误

[解决方案]

 1.将Java String转换为native String之后,调用ReleaseStringUTFChars释放

if (MNull != pszPath && MNull != strJString)
{
     env->ReleaseStringUTFChars(strJString, pszPath);
}

2.用完java传递过来的obj后,调用(env)->DeleteLocalRef(obj);释放


5、

【Log信息】

requestFeature() must be called before adding content

【场景应用】

编写Activity时,想要实现Activity无标题、无状态栏

requestWindowFeature(Window.FEATURE_NO_TITLE);  //取消标题
setContentView(R.layout.logo); //加载布局,一定要写在中间  
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  WindowManager.LayoutParams.FLAG_FULLSCREEN);  //取消状态栏
【原因分析】

出现该错误信息,是因为加载布局放在了取消标题之前。这和代码的执行顺序有关,若一开始先加载布局,那就会访问R.java类中的属性,之后再去访问wiget,就会出错。

【解决方案】

加载布局一定要写在取消标题和取消状态栏之间


6、

【Log信息】

android.view.WindowLeaked: Activity com.android.music.LoadingActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView
{67c9c01 V.E...... R......D 0,0-832,434} that was originally added here

【完整log信息】

(170810_21:08:54.861)01-01 02:44:50.563 1382 1382 E WindowManager: android.view.WindowLeaked: Activity com.android.music.LoadingActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView
{67c9c01 V.E...... R......D 0,0-832,434}
that was originally added here
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.view.ViewRootImpl.<init>(ViewRootImpl.java:462)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:306)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.Dialog.show(Dialog.java:326)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at com.android.music.LoadingActivity.onCreate(LoadingActivity.java:49)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.Activity.performCreate(Activity.java:6309)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2523)
(170810_21:08:54.870)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2658)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.ActivityThread.-wrap11(ActivityThread.java)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1492)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at android.os.Handler.dispatchMessage(Handler.java:111)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at android.os.Looper.loop(Looper.java:207)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at android.app.ActivityThread.main(ActivityThread.java:5737)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at java.lang.reflect.Method.invoke(Native Method)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
(170810_21:08:54.871)01-01 02:44:50.563 1382 1382 E WindowManager: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

【原因分析】 

(1)

You're trying to show a Dialog after you've exited an Activity.

(2)

This error can be a little misleading in some circumstances (although the answer is still completely accurate)
 - i.e. in my case an unhandled Exception was thrown in an AsyncTask, which caused the Activity to shutdown, then an open progressdialog caused this Exception.. so the 'real' exception was a little earlier in the log

(3)

Call dismiss() on the Dialog you created in before exiting your Activity, e.g. in onPause() or onDestroy()

【解决方案】

   在LoadingActivity的onDestroy()函数中添加progressDialog.dismiss()

7、

【Log信息】

java.lang.RuntimeException: Unable to resume activity {com.android.music/com.android.music.MediaPlaybackActivity}: java.lang.IllegalStateException: stableCount < 0: -1

【完整log】

java.lang.RuntimeException: Unable to resume activity {com.android.music/com.android.music.MediaPlaybackActivity}: java.lang.IllegalStateException: stableCount < 0: -1
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3318)
	at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3349)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1536)
	at android.os.Handler.dispatchMessage(Handler.java:111)
	at android.os.Looper.loop(Looper.java:207)
	at android.app.ActivityThread.main(ActivityThread.java:5737)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:832)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:722)
Caused by: java.lang.IllegalStateException: stableCount < 0: -1
	at android.os.Parcel.readException(Parcel.java:1607)
	at android.os.Parcel.readException(Parcel.java:1552)
	at android.app.ActivityManagerProxy.refContentProvider(ActivityManagerNative.java:3741)
	at android.app.ActivityThread.releaseProvider(ActivityThread.java:5203)
	at android.app.ContextImpl$ApplicationContentResolver.releaseProvider(ContextImpl.java:2018)
	at android.content.ContentResolver$CursorWrapperInner.close(ContentResolver.java:2568)
	at com.android.music.MediaPlaybackActivity.contentPathToUri(MediaPlaybackActivity.java:2530)
	at com.android.music.MediaPlaybackActivity.getLrcInfo(MediaPlaybackActivity.java:2468)
	at com.android.music.MediaPlaybackActivity.initLrc(MediaPlaybackActivity.java:2440)
	at com.android.music.MediaPlaybackActivity.updateTrackInfo(MediaPlaybackActivity.java:2070)
	at com.android.music.MediaPlaybackActivity.onResume(MediaPlaybackActivity.java:689)
	at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1268)
	at android.app.Activity.performResume(Activity.java:6384)
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3303)
	... 8 more

$** *** *** *** *** *** *** *** Exception *** *** *** *** *** *** *** **$

【原因分析】

  持引用时间太长,有被关闭的可能

而具体到MediaPlaybackActivity.java的contentPathToUri函数:


猜测是因为调用了两次close。所以改为只保留finally 代码块的close。即:

关于Cursor防止内存泄露的问题:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0731/1498.html

8、关于Adapter的The content of the adapter has changed问题分析

【Log信息】

Backtrace: 
Process: com.android.music
Flags: 0x3888be65
Package: com.android.music v23 (6.0-1499668367)
Build: autochips/full_ac83xx_evb/ac83xx_evb:6.0/MRA58K/1499665088:userdebug/test-keys
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(16908298, class com.android.music.TouchInterceptor) with Adapter(class com.android.music.PlaylistBrowserActivity$PlaylistListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1593)
at android.widget.ListView.setSelectionInt(ListView.java:2072)
at android.widget.AbsListView.resurrectSelection(AbsListView.java:5811)
at android.widget.AbsListView.onFilterComplete(AbsListView.java:6498)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5737)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:832)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:722)
$** *** *** *** *** *** *** *** Exception *** *** *** *** *** *** *** **$

【出现场景】

  Monkey Test for Music

【原因分析】

Exception解释:Adapter的数据内容已经改变,但是ListView却未接到通知。要确保不在后台线程中修改Adapter的数据内容,而要在UI Thread中修改。确保Adapter的数据内容改变时一定要调用notifyDataSetChanged()方法。

Android源码中该Exception的抛出位置,在ListView的layoutChildren()方法

// Handle the empty set by removing all views that are visible
// and calling it a day
if (mItemCount == 0) {
    resetList();
    invokeOnItemScrollListener();
    return;
} else if (mItemCount != mAdapter.getCount()) {
    throw new IllegalStateException("The content of the adapter has changed but "
            + "ListView did not receive a notification. Make sure the content of "
            + "your adapter is not modified from a background thread, but only "
            + "from the UI thread. [in ListView(" + getId() + ", " + getClass()
            + ") with Adapter(" + mAdapter.getClass() + ")]");
}
即, 当ListView缓存的数据Count和ListView中Adapter.getCount()不等时,会抛出该异常。 当后台扫描程序执行完毕后,adapter获取到的数据更新,但是没有及时通知到listView ,所以出现了上述JE中描述的,listView的内容与adapter.getCount不等。

【解决方案】

当playlistListAdapter改变了游标之后,就notifyDataSetChange()。


在红框后面,添加mAdapter.notifyDataSetChange();

参考链接:http://www.cnblogs.com/monodin/p/3874147.html


9、ClasscastException类型转换错误

【Log信息】

java.lang.ClassCastException: com.android.settings.notification.NotificationBackend$AppRow cannot be cast to com.android.settings.applications.AppStateAppOpsBridge$PermissionState
at com.android.settings.applications.DrawOverlayDetails.getSummary(DrawOverlayDetails.java:166)

【原因分析】

类型转换错误出现的原因,见如下分析:

Animal表示动物,Dog表示狗,是动物的子类;Cat表示猫,是动物的子类。则如下:
Animal a1 = new Dog( ); //1
Animal a2 = new Cat( ); //2

Dog d1 = (Dog)a1;  //3
Dog d2 = (Dog)a2; //4

第3行和4行,从表面意思来看都是把动物(Animal)强制转换为狗(Dog),但是第4行代码将产生Java.lang.ClassCastException。原因是要把猫(a2这只动物是猫)转换成狗,而第3行中是把狗转换成狗,所以可以。

从上面的例子可以看出,java.lang.ClassCastException是进行强制类型转换的时候产生的异常,强制类型转换的前提是父类引用指向的对象的类型是子类的时候才可以进行强制转换,如果父类引用指向的对象的类型不是子类的时候将产生java.lang.ClassCastException异常。就上面a1和a2都是动物,但是a1是一只狗,而a2是一只猫,所以要把a1转换成狗可以,因为a1本身就是狗,而a2是只猫,所以要转换成狗就出错了。

遇到这样的异常如何解决?如果知道要访问的对象的具体类型,直接转换成该类型即可。如果不能确定类型,可以通过下面的两种方式进行处理(假设对象为o):

1、通过o.getClass().getName()得到具体的类型,可以通过输出语句输出这个类型,然后根据类型进行具体的处理;
2、通过if(o instanceof 类型)的语句来判断o的类型是什么

上面所贴的setting的错误,具体到代码是:


 entry.extraInfo的类型是Object,具体到具体类型可能不是PermissionState

【Solution】


判断是否为PermissionState类型,如果不是则不执行该语句。

猜你喜欢

转载自blog.csdn.net/u011386173/article/details/54630886