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 ...
随机推荐
- android 很多应用中用到的 listView + viewPager
比如网易啊啥的, 有些界面的 listview 第一行是可以 左右滑动的 viewpager,当滑动下面listView的时候 会一起滑动上去 工程目录: 效果图: ...
- HTML5基础扩展——地理位置、本地存储、缓存
HTML5扩展,继上两篇博客,我们来看一下HTML5的一些扩展的功能,由于HTML5更多是为了兼容电脑浏览器,安卓浏览器,苹果浏览器更多浏览器,或者说为这些浏览器提供一个统一的标准.因此目前在手机上的 ...
- 在centos服务器上启用ipv6地址
随着互联网世界日新月异的发展,ipv6好像已经成为一种必不可少的趋势,但是当前国内机房大部分还不能支持ipv6,腾讯云亦如此.同时,现在有部分程序在服务器上运行的时候,需要服务器能监听一个ipv6地址 ...
- php随机生成汉字实现方法
GB 2312-80 是中国国家标准简体中文字符集,全称<信息交换用汉字编码字符集·基本集>,由中国国家标准总局发布,1981年5月1日实施.GB2312 编码通行于中国大陆:新加坡等地也 ...
- 对象序列化与反序列化(二进制 byte[])
.序列化 public static byte[] SerializeObject(object obj) { if (obj == null) return null; MemoryStream m ...
- ASP入门(七)-Response小案例
我们通过ASP来创建一个年月日的选择框,年份从1950到2000年,如果手动输入HTML代码,其中的<option>列表项目要写94个 (51年 + 12月 + 31天),很是繁琐. 代码 ...
- innerWidth outerWidth
在jQuery中: 一.width()方法用于获得元素宽度: 二.innerWidth()方法用于获得包括内边界(padding)的元素宽度; 三.outerWidth()方法用于获得包括内边界(pa ...
- 初探iOS网络开发,数据解析。
通过大众点评平台开发来简单了解一下,oc的网络编程和数据解析(json) 首先我们需要到大大众点评开发者平台申请一个key.http://developer.dianping.com/app/tech ...
- Jackcard类似度和余弦类似度(向量空间模型)的java实现
版权声明:本文为博主原创文章,地址:http://blog.csdn.net/napoay,转载请留言. 总结Jackcard类似度和余弦类似度. 一.集合的Jackcard类似度 1.1Jackca ...
- FIS前端集成解决方案
FIS前端集成解决方案-文档结构 什么是FIS 部署FIS FIS基本使用 模块定义 加载方式 调用Tangram 2.0 FIS开发实例 --附件下载-- 什么是FIS FIS提供了一套贯穿开发流程 ...