1

数秒ごとに更新されるRecyclerViewアダプタがあります。たびに、それがサーバーからデータを取得しますどのAsyncTaskを呼び出して、アダプタの内側にある次のメソッドを呼び出します(私はいくつかの行を削除し、彼らはこの問題に影響を与えません)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) 
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 0これは私のAsyncTaskのonPostExecute()でありますonBindViewHolder()でも呼び出されます):

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

アクティビティの移動中にAsyncTaskがキャンセルされる場合、updateItem()メソッドはどのように実行されますか? – SlowAndSteady

+0

外観がない場合は、AsyncTaskが完了したため、成功した場合はupdateItem()メソッドが呼び出されます。しかし、ユーザーがアプリを閉じたり、別のアクティビティに行くとクラッシュします。それは真剣に瞬時に起こるものです。しかし、まだ完了していないときにメソッドがキャンセルされた場合でも、タスクはキャンセルされ、updateItem()は呼び出されません。 –

+0

AsyncTaskを「キャンセル」することを「完了」するのは混乱しています。 onPauseまたはonStopのAsyncTaskでcancel()メソッドを呼び出していますか? – SlowAndSteady

答えて

0

ここは問題だと思います。

 Glide.with(context). 

クズ、ここではアクティビティが破壊され、それでも破壊されたアクティビティのコンテキストが使用されています。

0

Glideが呼び出されるまでにアクティビティやコンテキストが破壊されたため、クラッシュが発生しています。私はあなたが積極的なGCを持つデバイス上にいるか、 "開発者オプション"で "バックグラウンドで活動を続けないでください"を有効にしていると思います。

がクラッシュを防ぐために、私はそれがnullチェックを追加するために十分だと思う:

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

私はグライドがコンテキストに弱いか強い参照があるかどうかわからないです。これによりメモリリークが発生する可能性があります。理想的には、アクティビティを破棄するときにAsyncTaskをキャンセルする必要があります。そのアプローチをとることができない場合は、設計を再考する必要があります。

+0

あなたの提案をお寄せいただきありがとうございます。私はこの方法を使用しており、ユーザーの問題が修正されたことを願っています。私はこの問題を再現することはできませんが、私のベータユーザーはできます。 –

+0

更新:悲しいことに、これは私の問題を解決していない、もう少し複雑に思える。 –

+0

「開発者向けオプション」の「バックグラウンドでアクティビティを保存しない」を有効にすることで、この問題を再現できるかどうか確認できますか? – SlowAndSteady

関連する問題