RecyclerView中的AsyncTask抛出您无法在回调

时间:2016-11-05 14:28:14

标签: java android android-asynctask android-recyclerview android-glide

我有一个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);
        }
    }

//编辑:

我也尝试从适配器中取消任务,因为我无法从Activity本身取消它(FavoritesUpdateTask在适配器内部,也就是在onBindViewHolder()中调用的地方):

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

2 个答案:

答案 0 :(得分:0)

我认为..这就是问题所在。

        Glide.with(context).

Cuz,这里的活动被破坏了,它仍在使用被破坏活动的上下文。

答案 1 :(得分:0)

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

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

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

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