你不能在回调时开始加载一个被销毁的activity



我有一个每隔几秒钟更新一次的RecyclerView适配器。每次调用AsyncTask时,它将从服务器检索数据,然后调用适配器内部的以下方法:

public static void updateItem(final FavoritesViewHolder holder, DBHelper dbHelper, int position, Channel channel, Context context, boolean success) {
            Glide.with(context).load(channel.getAvatar())
                    .error(R.drawable.youtube_default_avatar)
                    .placeholder(R.drawable.youtube_default_avatar)
                    .into(holder.channelAvatarView);
            dbHelper.updateFavorites(channels.get(position));
            Glide.get(context).clearMemory();
    }

(我删除了几行,它们对这个问题没有影响)

但是,如果用户快速关闭应用程序或转到另一个AsyncTask刚刚调用该方法(是的,AsyncTask正在被取消,不用担心,它成功完成并调用此方法),Glide抛出以下错误:

java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
                                                                                    at com.bumptech.glide.manager.RequestManagerRetriever.assertNotDestroyed(RequestManagerRetriever.java:134)
                                                                                    at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:102)
                                                                                    at com.bumptech.glide.manager.RequestManagerRetriever.get(RequestManagerRetriever.java:87)
                                                                                    at com.bumptech.glide.Glide.with(Glide.java:629)
                                                                                    at it.bjarn.xxx.xxx.adapters.FavoritesAdapter.updateItem(FavoritesAdapter.java:204)
                                                                                    at it.bjarn.xxx.xxx.tasks.FavoriteUpdateTask.onPostExecute(FavoriteUpdateTask.java:104)
                                                                                    at it.bjarn.xxx.xxx.tasks.FavoriteUpdateTask.onPostExecute(FavoriteUpdateTask.java:27)
                                                                                    at android.os.AsyncTask.finish(AsyncTask.java:667)
                                                                                    at android.os.AsyncTask.-wrap1(AsyncTask.java)
                                                                                    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:684)
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                    at android.os.Looper.loop(Looper.java:154)
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

这是AsyncTask的onPostExecute():

protected void onPostExecute(AsyncTaskResult<Channel> result) {
        if (result.getError() != null) {
            Log.e("FavoritesUpdateTask", "Exception while retrieving  results: " + result.getError().toString());
            Glide.get(mContext).clearMemory();
        } else if (isCancelled()) {
            Log.d("FavoritesUpdateTask", "Cancelled");
            Glide.get(mContext).clearMemory();
        } else {
            Log.d("FavoritesUpdateTask", "Succesfully returned channel object");
            FavoritesAdapter.updateItem(mHolder, mDbHelper, mPosition, result.getResult(), mContext, true);
        }
    }

//编辑:

我也试图从适配器取消任务,因为我不能从活动本身取消它(FavoritesUpdateTask是在适配器内,这也是它在onBindViewHolder()中被调用的地方):

@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
    if (favoriteUpdateTask != null) {
        favoriteUpdateTask.cancel(true);
    }
}

我认为……问题在这里。

        Glide.with(context).

崩溃正在发生,因为您的活动/上下文在调用Glide时被销毁。我猜你是在一个具有侵略性GC的设备上,或者你在"开发人员选项"中启用了"不要在后台保持活动"。

为了防止崩溃,我想添加一个null检查就足够了:

if(context != null && (!(Activity)context).isFinishing()) {
   updateItem()
}

我不确定Glide对上下文的引用是弱还是强。这可能导致内存泄漏。理想情况下,您应该在销毁活动时取消AsyncTask。如果你不能采用这种方法,你应该重新考虑你的设计。

最新更新