notification复用中抛出can not parcel recyle’s bitmap

由于对android重用思想的根深蒂固,所以我在使用通知的使用并不是stop之后再次start,而是只存在一个对象,直接startforgeound,

但是在remoteview中将之前bitmap.recyle时,会出现can not parcel recyle’s bitmap,bitmap

原始代码是这样的.

bitmap(之前通知现实的图片)

bitmap.recyle();

mRemoteView.setImageViewResource(R.id.notification_bg, R.drawable.log);

startForeground();

 

foreground死掉了,为什么呢?我发现每次执行与bitmap相关的方法,remoteviews中的bitmapcache都会去获取ID,这个ID就是bitmapcache中的index,因为removateviews的缺陷,导致并非我们设置bitmapnull时便会移除原本的action(remoteviews中的内部类,每次执行关于bitmap的方法都会new一个新的,添加到默认数组中),这就导致bitmapcache中的arraylist<bitmap>只增不减,为此我们无法将bitmap进行recyle,如果我们recyle便会抛出can not parcel recyle’s bitmap 错误,因为它竟然将bitmapcache中的arraylist<bitmap>全部parcel,如果我们不recyle,就会导致gc亚历山大的问题(我是想重用notification的,虽然google不建议我们重用,因为可能引起ANR,但是呢,重用如果只有单一功能的notification,重用还是有价值的,毕竟用户不希望在重复刷新nofication时,内存直升太过明显,那显然是很操蛋的体验,不要太相信GC线程,比如service只用了2M,而由于频繁操作,heap到达了10M,那么这个10M显示在应用程序列表里会持续很长时间),解决方法很简单:

private boolean removeBitmapCache() {
try {
Object obj = Tool.getField(mRemoteView, "mBitmapCache").get(mRemoteView);
if (obj != null) {
List<Bitmap> mps = (List<Bitmap>) Tool.getField(obj, "mBitmaps").get(obj);
if (mps != null) {
mps.clear();
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}


 

使用java反射,得到bitmapcachearraylist,进行清空.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`onNotificationPosted` 是 Android 系统的一个通知监听回调方法,它可以在通知被 Android 系统显示在状态栏上时被调用。该方法是 `NotificationListenerService` 类的一个方法,需要继承该类并实现该方法才能监听通知。 当有新的通知被显示在状态栏上时,`onNotificationPosted` 方法就会被回调,并且会传入一个 `StatusBarNotification` 对象,该对象包含了通知的详细信息,如通知的 ID、包名、内容、标题等。开发者可以通过该对象来获取通知的详细信息,并进行相应的处理。 以下是一个简单的 `NotificationListenerService` 的使用示例: ```java public class MyNotificationListenerService extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { // 获取通知的详细信息 int notificationId = sbn.getId(); String packageName = sbn.getPackageName(); String notificationTitle = sbn.getNotification().extras.getString(Notification.EXTRA_TITLE); String notificationText = sbn.getNotification().extras.getString(Notification.EXTRA_TEXT); // 处理通知 } @Override public void onNotificationRemoved(StatusBarNotification sbn) { // 通知被移除时的回调 } } ``` 需要注意的是,为了使用 `NotificationListenerService`,需要在 AndroidManifest.xml 文件注册该服务,并添加相应的权限声明,如下所示: ```xml <service android:name=".MyNotificationListenerService" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service> ``` 同时,需要在系统设置开启该应用的通知访问权限,才能正常监听通知。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值