使用Fresco将图像加载到通知时,无法包含回收的位图错误

时间:2017-10-18 12:31:06

标签: java android bitmap android-notifications

我已按照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构建通知,以便在将新图像加载到通知时从不会产生此错误?

1 个答案:

答案 0 :(得分:1)

检查以下内容:

 Bitmap largeIcon = (artwork != null && !artwork.isRecycled()) ? artwork : BitmapFactory.decodeResource(getResources(), R.drawable.empty_album);

创建你的图标,因为我怀疑你的作品不是空的,而是在代码的一部分中回收,我们看不到