转载请注明出处:http://blog.csdn.net/llew2011/article/details/79054457
Android开发适配问题一直是一个让人头疼的话题,由于国内很多厂商都有对原生Android系统做不同的定制,结果导致适配起来很麻烦。印象最深的一个适配是让Notification的背景色做到和系统通知栏背景色一致,然后就是想各种办法做适配……近来在Bugly上查看统计APP的crash日志的时候发现有一个crash日志很诡异,该crash只发生在HuaWei手机上,截取部分Crash日志如下所示:
java.lang.AssertionError:Register too many Broadcast Receivers
android.app.LoadedApk.checkRecevierRegisteredLeakLocked(LoadedApk.java:1010)
android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:1038)
android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1476)
android.app.ContextImpl.registerReceiver(ContextImpl.java:1456)
android.app.ContextImpl.registerReceiver(ContextImpl.java:1450)
android.content.ContextWrapper.registerReceiver(ContextWrapper.java:586)
com.tencent.sharp.jni.TraeAudioManager$TraeAudioManagerLooper.void _post_stopService()(TraeAudioManager.java:1982)
com.tencent.sharp.jni.TraeAudioManager$TraeAudioManagerLooper.void stopService()(TraeAudioManager.java:1628)
com.tencent.sharp.jni.TraeAudioManager$TraeAudioManagerLooper$2.void handleMessage(android.os.Message)(TraeAudioManager.java:1695)
android.os.Handler.dispatchMessage(Handler.java:105)
android.os.Looper.loop(Looper.java:156)
com.tencent.sharp.jni.TraeAudioManager$TraeAudioManagerLooper.void run()(TraeAudioManager.java:1891)
根据日志信息看到抛出的异常为:Register too many Broadcast Receivers,翻译过来就是注册的BroadcastReceiver太多导致的。根据调用的栈信息,是TraeAudioManager类的内部类TraeAudioManager的_post_stopService()方法内注册BroadcastReceiver过多导致应用crash的。所以我们猜测该crash很有可能是在_post_stopService()方法内部注册BroadcastReceiver前没有进行反注册操作导致的。由于TraeAudioManager类是鹅厂SDK中的类,因此只能反编译查看TraeAudioManager类的实现方式,反编译后的TraeAudioManager.class主要代码如下;
public class TraeAudioManager extends BroadcastReceiver {
// 省略部分代码
class TraeAudioManagerLooper extends Thread {
// 省略部分代码
public TraeAudioManagerLooper(TraeAudioManager var2) {
this._parent = var2;
this.start();
// 省略部分代码
}
void stopService() {
AudioDeviceInterface.LogTraceEntry(" _enabled:" + (this._enabled?"Y":"N") + " activeMode:" + TraeAudioManager.this._activeMode);
if(this._enabled) {
// 省略部分代码
this._post_stopService();
// 省略部分代码
}
}
public void run() {
Looper.prepare();
this.mMsgHandler = new Handler() {
public void handleMessage(Message var1) {
// 省略部分代码
if(var1.what == '耄') {
TraeAudioManagerLooper.this.startService(var6);
} else if(!TraeAudioManagerLooper.this._enabled) {
Intent var7 = new Intent();
TraeAudioManager.this.sendResBroadcast(var7, var6, 1);
} else {
switch(var1.what) {
case 32773:
TraeAudioManagerLooper.this.stopService();
break;
}
}
};
// 省略部分代码
}
void _post_stopService() {
try {
if(TraeAudioManager.this._bluetoothCheck != null) {
TraeAudioManager.this._bluetoothCheck.release();
}
TraeAudioManager.this._bluetoothCheck = null;