我如何从我的片段中获取上下文以进行我的匕首依赖注入

How do I get the context from my fragment for my dagger dependency injection

注意:请参阅更新 2 了解我目前拥有的内容


目前在我片段的 onCreateView() 中,我有一个像这样初始化的 recyclerview 适配器:

Query query = couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery();
LiveQuery liveQuery = query.toLiveQuery();

if (myAdapter == null) {
    myAdapter = new MyAdapter(getActivity().getApplication(), new ArrayList<>(), getActivity(), liveQuery);
}

这是上述适配器的构造函数:

public MyAdapter(Application application,
                 List<MyViewHolder> myViewHolderList,
                 Context context,
                 LiveQuery liveQuery) {
    this.myViewHolderList = myViewHolderList;
    this.context = context;
    this.liveQuery = liveQuery
    LiveQuery.ChangeListener listener = new LiveQuery.ChangeListener() {
        @Override
        public void changed(LiveQuery.ChangeEvent event) {
            ((Activity)MyAdapter.this.context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    enumerator = event.getRows();
                    notifyDataSetChanged();
                }
            });
        }
    };
    ((MainApplication)application).getAppComponent().inject(this);
    this.liveQuery.addChangeListener(listener);
    this.liveQuery.start();
}

但最近我正在尝试学习如何使用 Dagger 2 进行依赖注入,我认为我不应该 "new" 除了 Dagger 的 AppModule 之外的任何地方?

那么,当我需要片段的上下文时,我该如何在我的 AppModule class 中编写 provide 方法呢?或者我做这个注射完全错误并且完全错过了这个想法?

上下文变量仅在这一行中使用过:

((Activity)MyAdapter.this.context).runOnUiThread(new Runnable()...

这是我的 AppModule 中目前的内容 class:

@Provides
MyAdapter provideMyAdapter() {
    return new MyAdapter(mainApplication, new ArrayList<>(), idk_context, getLiveQuery);
}

private LiveQuery getLiveQuery() {
    return couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery().toLiveQuery();
}

我不确定我应该如何找到一种方法来使用 getActivity() 从我的片段中获取上下文。

有什么提示吗?


更新:这样做可以吗?

@Module
public class AppModule {
    private MyFragment myFragment = new MyFragment(); // So I just initialize this here instead
    private MainApplication mainApplication;

    public AppModule(MainApplication mainApplication) {
        this.mainApplication = mainApplication;
    }

    @Provides
    MyAdapter provideMyAdapter() {
        return new MyAdapter(mainApplication, new ArrayList<>(), myFragment.getActivity(), getLiveQuery());
    }

    @Singleton
    @Provides
    MyFragment provideMyFragment() {
        return myFragment;
    }

    private LiveQuery getLiveQuery() {
        return couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery().toLiveQuery();
    }
}

更新 2:我最终这样做了:我添加了一个东西来提供 activity 并收工。这样可以吗?

@Module
public class AppModule {
    private MainApplication mainApplication;

    public AppModule(MainApplication mainApplication) {
        this.mainApplication = mainApplication;
    }

    @Provides
    @Singleton
    MyAdapter provideMyAdapter(Activity activity, LiveQuery liveQuery) {
        return new MyAdapter(mainApplication, new ArrayList<>(), activity, liveQuery);
    }

    @Provides
    @Singleton
    MyFragment provideMyFragment() {
        return new MyFragment();
    }

    // I added this method and just let this provide the activity to my provideAdapter method.
    @Provides
    @Singleton
    Activity provideActivity(MyFragment myFragment) {
        return myFragment.getActivity();
    }

    @Provides
    @Singleton
    LiveQuery provideLiveQuery() {
        return couchLocalDb.getDatabase().getView(MY_VIEW_NAME).createQuery().toLiveQuery();
    }
}

这是新的构造函数

public MyAdapter(Application application,
                 List<MyViewHolder> myViewHolderList,
                 Activity activity,
                 LiveQuery liveQuery) {
    this.myViewHolderList = myViewHolderList;
    this.liveQuery = liveQuery
    LiveQuery.ChangeListener listener = new LiveQuery.ChangeListener() {
        @Override
        public void changed(LiveQuery.ChangeEvent event) {
            (activity).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    enumerator = event.getRows();
                    notifyDataSetChanged();
                }
            });
        }
    };
    ((MainApplication)application).getAppComponent().inject(this);
    this.liveQuery.addChangeListener(listener);
    this.liveQuery.start();
}

这样做可以吗?不是坏习惯还是什么?

是的,几乎没问题,但我认为如果您为片段创建一些范围会更好。因为如果你有大量的片段,你的应用程序将在你需要之前创建你的片段,并且它会在你的应用程序运行时一直存在

您可以使用 getActivity(),它 returns 与片段关联的 activity。
activity 是上下文(因为 Activity 扩展了上下文)。
这是 FragmentContext 的示例:

//import android.app.Fragment;
import android.support.v4.app.Fragment
public class CalendarFragment extends Fragment
{
    static Context mContext      = null;                   //member variable
    ...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    mContext = this.getActivity();                         //set mContext
    ((Activity) mContext).startManagingCursor(notesCursor);//cast to Activity
    ...