MessageListActivity has leaked IntentReceiver
1. 在MessagelistActivity中出现has leaked IntentReceiver的异常。异常日志如下。
07-15 08:09:53.211: E/ActivityThread(15491): Activity com.txrj.sms.activity.MessageListActivity has leaked IntentReceiver com.txrj.sms.activity.MessageListActivity$6@41e189d0 that was originally registered here. Are you missing a call to unregisterReceiver()?     
07-15 08:09:53.211: E/ActivityThread(15491): android.app.IntentReceiverLeaked: Activity com.txrj.sms.activity.MessageListActivity has leaked IntentReceiver com.txrj.sms.activity.MessageListActivity$6@41e189d0 that was originally registered here. Are you missing a call to unregisterReceiver()?     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:763)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:567)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1167)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:1154)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:1148)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:348)     
07-15 08:09:53.211: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity.getDeliveryIntent(MessageListActivity.java:247)     
07-15 08:09:53.211: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity.sendMessage(MessageListActivity.java:196)     
07-15 08:09:53.211: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity.access$14(MessageListActivity.java:190)     
07-15 08:09:53.211: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity$2.onClick(MessageListActivity.java:120)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.view.View.performClick(View.java:3567)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.view.View$PerformClick.run(View.java:14224)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.os.Handler.handleCallback(Handler.java:605)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.os.Handler.dispatchMessage(Handler.java:92)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.os.Looper.loop(Looper.java:137)     
07-15 08:09:53.211: E/ActivityThread(15491):     at android.app.ActivityThread.main(ActivityThread.java:4517)     
07-15 08:09:53.211: E/ActivityThread(15491):     at java.lang.reflect.Method.invokeNative(Native Method)     
07-15 08:09:53.211: E/ActivityThread(15491):     at java.lang.reflect.Method.invoke(Method.java:511)     
07-15 08:09:53.211: E/ActivityThread(15491):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)     
07-15 08:09:53.211: E/ActivityThread(15491):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)     
07-15 08:09:53.211: E/ActivityThread(15491):     at dalvik.system.NativeStart.main(Native Method)     
07-15 08:09:53.221: E/ActivityThread(15491): Activity com.txrj.sms.activity.MessageListActivity has leaked IntentReceiver com.txrj.sms.activity.MessageListActivity$5@41df9b80 that was originally registered here. Are you missing a call to unregisterReceiver()?     
07-15 08:09:53.221: E/ActivityThread(15491): android.app.IntentReceiverLeaked: Activity com.txrj.sms.activity.MessageListActivity has leaked IntentReceiver com.txrj.sms.activity.MessageListActivity$5@41df9b80 that was originally registered here. Are you missing a call to unregisterReceiver()?     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:763)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:567)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1167)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:1154)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:1148)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:348)     
07-15 08:09:53.221: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity.getSentIntent(MessageListActivity.java:232)     
07-15 08:09:53.221: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity.sendMessage(MessageListActivity.java:195)     
07-15 08:09:53.221: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity.access$14(MessageListActivity.java:190)     
07-15 08:09:53.221: E/ActivityThread(15491):     at com.txrj.sms.activity.MessageListActivity$2.onClick(MessageListActivity.java:120)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.view.View.performClick(View.java:3567)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.view.View$PerformClick.run(View.java:14224)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.os.Handler.handleCallback(Handler.java:605)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.os.Handler.dispatchMessage(Handler.java:92)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.os.Looper.loop(Looper.java:137)     
07-15 08:09:53.221: E/ActivityThread(15491):     at android.app.ActivityThread.main(ActivityThread.java:4517)     
07-15 08:09:53.221: E/ActivityThread(15491):     at java.lang.reflect.Method.invokeNative(Native Method)     
07-15 08:09:53.221: E/ActivityThread(15491):     at java.lang.reflect.Method.invoke(Method.java:511)     
07-15 08:09:53.221: E/ActivityThread(15491):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)     
07-15 08:09:53.221: E/ActivityThread(15491):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)     
07-15 08:09:53.221: E/ActivityThread(15491):     at dalvik.system.NativeStart.main(Native Method)
2. 出现异常原因分析。在发送信息时,创建了两个PendingIntent,它们是调用方法getBroadcast来发送广播。在此之前调用registerBroadcast注册广播,查看代码找不到注销广播的语句,所以导致出现leaked IntentReceiver的异常。以下是改正之后的代码。
private PendingIntent getSentIntent(final Uri uri) {    
    BroadcastReceiver receiver = new BroadcastReceiver(){
        @Override    
        public void onReceive(Context context, Intent intent) {     
            mContext.unregisterReceiver(this);      
            int resultCode = getResultCode();     
            if(resultCode == RESULT_OK) {     
                Toast.makeText(context, "send message success.", Toast.LENGTH_SHORT).show();     
                //Log.i("txrjsms", "send message success.");     
                updateMsgType(uri, Sms.MESSAGE_TYPE_SENT);     
            } else if(resultCode == SmsManager.RESULT_ERROR_GENERIC_FAILURE) {     
                Toast.makeText(context, "Generic failure.", Toast.LENGTH_SHORT).show();     
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);     
            } else if(resultCode == SmsManager.RESULT_ERROR_NO_SERVICE) {     
                Toast.makeText(context, "service is currently unavailable.", Toast.LENGTH_SHORT).show();     
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);     
            } else if(resultCode == SmsManager.RESULT_ERROR_NULL_PDU) {     
                Toast.makeText(context, "no pdu provided.", Toast.LENGTH_SHORT).show();     
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);     
            } else if(resultCode == SmsManager.RESULT_ERROR_RADIO_OFF) {     
                Toast.makeText(context, "radio was explicitly turned off.", Toast.LENGTH_SHORT).show();     
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);     
            }     
        }     
    };     
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_SEND_SMS);     
    mContext.registerReceiver(receiver, filter);      
    Intent sentIntent = new Intent(TxrjConstant.ACTION_SEND_SMS);     
    return PendingIntent.getBroadcast(mContext, 0, sentIntent, 0);     
}
private PendingIntent getDeliveryIntent() {    
    BroadcastReceiver receiver = new BroadcastReceiver(){
        @Override    
        public void onReceive(Context context, Intent intent) {     
            mContext.unregisterReceiver(this);     
            Toast.makeText(context, "message arrived.", Toast.LENGTH_SHORT).show();     
            //Log.i("txrjsms", "message arrived.");     
        }     
    };     
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_DELIVERY_SMS);     
    mContext.registerReceiver(receiver, filter);     
    Intent deliveryIntent = new Intent(TxrjConstant.ACTION_DELIVERY_SMS);     
    return PendingIntent.getBroadcast(mContext, 0, deliveryIntent, 0);     
}
3. 添加了注销广播接收器的语句之后还会有问题。比如,发出信息之后,对方有信息回复时,在MessageListActivity界面中无法将刚收到的信息显示出来。优化注册和注销Receiver的代码。以下是优化过的代码,将receiver作为实例变量来定义,在第一次获取sentIntert和deliveryIntent时创建并注册它们。在onDestroy方法中注销它们。
在sentReceiver中需要传递表示发送信息的uri。在调用getBroadcast时通过intent.putExtra放入Uri。在onReceive方法中通过intent.getParcelableExtra取出Uri。
private void createAndRegisterSentReceiver() {   
    sentReceiver = new BroadcastReceiver(){    
        @Override    
        public void onReceive(Context context, Intent intent) {    
            Uri uri = intent.getParcelableExtra(TxrjConstant.EXTRA_SENT_URI);     
            int resultCode = getResultCode();    
            if(resultCode == RESULT_OK) {    
                Toast.makeText(context, "send message success.", Toast.LENGTH_SHORT).show();    
                updateMsgType(uri, Sms.MESSAGE_TYPE_SENT);    
            } else if(resultCode == SmsManager.RESULT_ERROR_GENERIC_FAILURE) {    
                Toast.makeText(context, "Generic failure.", Toast.LENGTH_SHORT).show();    
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);    
            } else if(resultCode == SmsManager.RESULT_ERROR_NO_SERVICE) {    
                Toast.makeText(context, "service is currently unavailable.", Toast.LENGTH_SHORT).show();    
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);    
            } else if(resultCode == SmsManager.RESULT_ERROR_NULL_PDU) {    
                Toast.makeText(context, "no pdu provided.", Toast.LENGTH_SHORT).show();    
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);    
            } else if(resultCode == SmsManager.RESULT_ERROR_RADIO_OFF) {    
                Toast.makeText(context, "radio was explicitly turned off.", Toast.LENGTH_SHORT).show();    
                updateMsgType(uri, Sms.MESSAGE_TYPE_FAILED);    
            }    
        }    
    };    
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_SEND_SMS);    
    mContext.registerReceiver(sentReceiver, filter);    
}
private PendingIntent getSentIntent(final Uri uri) {   
    if(sentReceiver == null) {    
        createAndRegisterSentReceiver();     
    }    
    Intent sentIntent = new Intent(TxrjConstant.ACTION_SEND_SMS);    
    sentIntent.putExtra(TxrjConstant.EXTRA_SENT_URI, uri);     
    return PendingIntent.getBroadcast(mContext, 0, sentIntent, 0);    
}
deliveryReceiver使用类似的处理方法。代码如下所示。
private void createAndRegisterDeliveryIntent() {   
    deliveryReceiver = new BroadcastReceiver(){
        @Override   
        public void onReceive(Context context, Intent intent) {    
            mContext.unregisterReceiver(this);    
            Toast.makeText(context, "message arrived.", Toast.LENGTH_SHORT).show();    
        }    
    };    
    IntentFilter filter = new IntentFilter(TxrjConstant.ACTION_DELIVERY_SMS);    
    mContext.registerReceiver(deliveryReceiver, filter);    
}
private PendingIntent getDeliveryIntent() {   
    if(deliveryReceiver == null) {    
        createAndRegisterDeliveryIntent();    
    }    
    Intent deliveryIntent = new Intent(TxrjConstant.ACTION_DELIVERY_SMS);    
    return PendingIntent.getBroadcast(mContext, 0, deliveryIntent, 0);    
}
在onDestroy()方法中注销sentReceiver和deliveryReceiver。
protected void onDestroy() {   
    super.onDestroy();    
    getContentResolver().unregisterContentObserver(mInboxObserver);    
    if(sentReceiver != null) {    
        unregisterReceiver(sentReceiver);     
    }    
    if(deliveryReceiver != null) {    
        unregisterReceiver(deliveryReceiver);     
    }    
}
MessageListActivity has leaked IntentReceiver的更多相关文章
- Android学习系列(37)--App调试内存泄露之Context篇(下)
		接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ... 
- [Android Memory]    App调试内存泄露之Context篇(下)
		转载地址:http://www.cnblogs.com/qianxudetianxia/p/3655475.html 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用A ... 
- Android 之 WebView
		1:在AndroidManifest.xml中添加允许android访问网络权限. <uses-permission android:name="android.permission. ... 
- WebView全面学习(二)-- Native与js双方通信
		WebView全面学习(二)-- Native与js双方通信 Native与js通信的本质 Native与js通信的核心在于WebView. 两端的通信主要还是单向的.假如要完成js->Nati ... 
- android中常见的内存泄漏和解决的方法
		android中的内存溢出预计大多数人在写代码的时候都出现过,事实上突然认为工作一年和工作三年的差别是什么呢.事实上干的工作或许都一样,产品汪看到的结果也都一样,那差别就是速度和质量了. 写在前面的一 ... 
- StrictMode 详解
		StrictMode类是Android 2.3 (API 9)引入的一个工具类,可以用来帮助开发者发现代码中的一些不规范的问题.比如,如果你在UI线程中进行了网络或者磁盘操作,StrictMode就会 ... 
- Activity has leaked window that was originally added
		错误: E/WindowManager: android.view.WindowLeaked: Activity com.x.x.x has leaked window com.android.int ... 
- 数据库内存泄漏——A SQLiteConnection object for database '/data/data/.../databases/....db' was leaked!
		详细异常: A SQLiteConnection object for database '/data/data/.../database/....db' was leaked! Please ... 
- has leaked ServiceConnection com.baidu.location.LocationClient
		02-06 05:01:52.806: E/ActivityThread(1120): Activity com.project.xxxActivity $1@45fc5af8 that was or ... 
随机推荐
- DOS批处理中%cd%和%~dp0的异同分析
			在DOS的批处理中,有时候需要知道当前的路径.在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0. 这两个变量的用法和代表的内容是不同的. 1. %cd% 可以用在批处理 ... 
- SGU536 Berland Chess
			棋盘上白子只有一个国王 黑子给出 各子遵从国际象棋的走法 黑子不动,白子不能走进黑子的攻击范围以内 问白字能不能吃掉所有的黑子 直接搜索就好了,各子状态用二进制表示 不过每个子被吃之后攻击范围会改变 ... 
- Entity Framework 与 LINQ to SQL
			Entity Framework和LINQ to SQL到底有什么区别?这是一个很常见的问题.下面的表中简要罗列了两种技术的主要区别. LINQ to SQL Entity Framework 复杂度 ... 
- 为什么static数据成员一定要在类外初始化?(转)
			1.避免重复定义和初始化 <<c++ primer>>说在类外定义和初始化是保证static成员变量只被定义一次的好方法. 但,为什么static const int就可以在类 ... 
- RNN(Recurrent Neural Networks)公式推导和实现
			RNN(Recurrent Neural Networks)公式推导和实现 http://x-algo.cn/index.php/2016/04/25/rnn-recurrent-neural-net ... 
- group by 深入总结(转)
			http://www.cnblogs.com/wangtao_20/archive/2011/02/23/1959792.html 一.不兼容的语法问题. 先看使用如下sql:SELECT count ... 
- THINKPHP 验证码不显示
			最近同事将我之前使用Thinkphp做的一个项目从香港服务器迁移到国内,但却遇到了图片验证码不显示的问题 但我确认了以下可能的问题后还是没有解决 PHP是否已经安装GD库支持: 输出之前是否有任何的输 ... 
- How could I create a custom windows message?
			[问题] Our project is running on Windows CE 6.0 and is written in C++ . We have some problems with the ... 
- 以sb7code为基础创建一个基本的OpenGL项目
			以sb7code为基础创建一个基本的OpenGL项目 从github上面下载sb7code代码: https://github.com/openglsuperbible/sb7code 打开H ... 
- 25个Web前端开发工程师必看的国外大牛和酷站
			逛了一周国外大牛们的博客与酷站,真是满满的钦佩.震撼.羡慕.惊喜………… Web设计是一个不断变化的领域,因此掌握最新的发展趋势及技术动向对设计师来说非常重要.无论是学习新技术,还是寻找免费资源与工具 ... 
