2017-01-27 3 views
2

はこのようにアダプタを考える:あなたが見ることができるように、アクティビティ・インスタンスが意図打ち上げのために必要とされるRecyclerView.AdapterでContext/Activityインスタンスをリークしないでください。

public class MyAdapter extends RecyclerView.Adapter { 

    private final Activity mActivity; 
    private final List<Item> mItemList; 

    public MyAdapter(Activity activity, List<Item> itemList) { 
     this.mActivity = activity; 
     this.mItemList = itemList; 
    } 

    //[...] 

    public void onBindViewHolder(ViewHolder holder, int position) { 
     final Item i = mItemList.get(position); 
     holder.launchButton.setOnClickListener(new OnClickListener() { 
       @Override public void onClick(View v) { 
        mActivity.startActivity(i.getIntent()); 
      }); 
    } 

} 

。もちろん、それを行う他の方法がありますが(たとえばインターフェイスを使用するなど)、問題のポイントはアダプタのmActivityインスタンスへのハードリファレンスを維持することが安全であるかどうかです。

答えて

3

によってビューにコンテキストを提供して

ビューは、Contextを拡張しません。 Androidのガベージコレクションは、ルートオブジェクトからのオブジェクトへの強い参照がないとオブジェクトをリサイクルします。アダプタはRecyclerViewによって参照され、RecyclerViewはアクティビティが解放される前にガベージコレクションの対象となるため、アクティビティをリサイクルするまでにRecyclerViewはガベージコレクションの対象となり、ガベージコレクションからのアクティビティまた、アクティビティがアダプタへの参照を持っている場合は、2つのオブジェクトが互いに参照するだけで、ルートオブジェクトからはアクセスできないため、ガベージコレクションの対象となります。

+0

良い説明のための最良の答えとして選んだ – BamsBamx

1

このアプローチでは問題はありませんが、 startActivityを呼び出すためにActivityインスタンスを実際に必要とせず、Contextのいずれかが実行されます。 holder.launchButton.getContext()Contextのインスタンスを取得できます。

+0

View.getContext()について考えていませんでした – BamsBamx

1

はい、コンテキストインスタンスは、クラスインスタンスが存在するまで存在し続けることができます。あるいは、任意のビューからContextを取得することも、Contextを返すグローバルなApplicationクラスによって取得することもできます。 Androidははい、それは大丈夫です方法View.getContext()

関連する問題