我已按照http://frescolib.org/docs/images-in-notifications.html中的示例详细介绍了如何从网络加载图像并在通知中设置图像。
这是我的代码演示相同:
private void fetchNotificationImage(String image) {
ImageRequest imageRequest = ImageRequest.fromUri(image);
ImagePipeline pipeline = Fresco.getImagePipeline();
com.facebook.datasource.DataSource<CloseableReference<CloseableImage>> dataSource = pipeline.fetchDecodedImage(imageRequest, null);
dataSource.subscribe(new BaseBitmapDataSubscriber() {
@Override
protected void onNewResultImpl(Bitmap bitmap) {
artwork = bitmap;
updateNotification();
mediaSession.setMetadata(new MediaMetadataCompat.Builder().putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap).build());
}
@Override
protected void onFailureImpl(com.facebook.datasource.DataSource<CloseableReference<CloseableImage>> dataSource) {
artwork = BitmapFactory.decodeResource(getResources(), R.drawable.empty_album);
updateNotification();
mediaSession.setMetadata(new MediaMetadataCompat.Builder().putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, artwork).build());
}
},
UiThreadImmediateExecutorService.getInstance());
}
updateNotification
方法如下:
private void updateNotification() {
NotificationCompat.Action playPauseAction = playbackState.getState() == PlaybackStateCompat.STATE_PLAYING ?
createAction(R.drawable.ic_music_pause, "Pause", ACTION_PAUSE) :
createAction(R.drawable.ic_music_play, "Play", ACTION_PLAY);
setPlaybackState(playbackState.getState());
Bitmap largeIcon = artwork != null ? artwork : BitmapFactory.decodeResource(getResources(), R.drawable.empty_album);
Notification notification = new NotificationCompat.Builder(this)
.setPriority(Notification.PRIORITY_DEFAULT)
.setContentTitle(songTitle)
.setContentText(songArtist)
.setShowWhen(false)
.setSmallIcon(R.drawable.ic_stat_playing)
.setLargeIcon(largeIcon)
.addAction(createAction(R.drawable.ic_action_previous, "Previous", ACTION_PREVIOUS))
.addAction(playPauseAction)
.addAction(createAction(R.drawable.ic_action_next, "Next", ACTION_SKIP))
.setStyle(new NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.getSessionToken())
.setShowActionsInCompactView(1, 2))
.setContentIntent(startPendingIntent())
.build();
startForeground(1, notification);
}
它在大多数情况下效果很好。但是,我偶尔会得到Can't parcel a recycled bitmap exception
。这是完整的错误日志:
Fatal Exception: java.lang.IllegalStateException: Can't copy a recycled bitmap
at android.graphics.Bitmap.checkRecycled(Bitmap.java:400)
at android.graphics.Bitmap.createAshmemBitmap(Bitmap.java:713)
at android.graphics.drawable.Icon.convertToAshmem(Icon.java:391)
at android.app.Notification$Builder.build(Notification.java:3906)
at android.support.v4.app.NotificationCompatApi21$Builder.build(NotificationCompatApi21.java:127)
at android.support.v4.app.NotificationCompat$BuilderExtender.build(NotificationCompat.java:620)
at android.support.v4.app.NotificationCompat$NotificationCompatApi21Impl.build(NotificationCompat.java:853)
at android.support.v4.app.NotificationCompat$Builder.build(NotificationCompat.java:1861)
at com.radioafrica.music.service.MusicService.updateNotification(MusicService.java:890)
at com.radioafrica.music.service.MusicService.access$600(MusicService.java:140)
at com.radioafrica.music.service.MusicService$1.onPlayFromUri(MusicService.java:536)
at android.support.v4.media.session.MediaSessionCompat$Callback$StubApi23.onPlayFromUri(MediaSessionCompat.java:1414)
at android.support.v4.media.session.MediaSessionCompatApi23$CallbackProxy.onPlayFromUri(MediaSessionCompatApi23.java:41)
at android.media.session.MediaSession$CallbackMessageHandler.handleMessage(MediaSession.java:1216)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7409)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
如何使用Fresco
构建通知,以便在将新图像加载到通知时从不会产生此错误?
答案 0 :(得分:1)
检查以下内容:
Bitmap largeIcon = (artwork != null && !artwork.isRecycled()) ? artwork : BitmapFactory.decodeResource(getResources(), R.drawable.empty_album);
创建你的图标,因为我怀疑你的作品不是空的,而是在代码的一部分中回收,我们看不到