【问题标题】:How do I get the context from my fragment for my dagger dependency injection如何从我的片段中获取上下文以进行匕首依赖注入
【发布时间】:2017-03-25 01:46:32
【问题描述】:

注意:请参阅更新 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 进行依赖注入,我认为我不应该在 Dagger 的 AppModule 之外的任何地方都有“新”?

那么当我需要片段的上下文时,我将如何在我的 AppModule 类中为此编写提供方法?还是我做这个注射完全错了,完全错过了这个想法?

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

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

这是迄今为止我的 AppModule 类中的内容:

@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:我最终这样做了:我添加了一个东西来提供活动并收工。这样做可以吗?

@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();
}

这样做可以吗?不是不好的做法吗?

【问题讨论】:

  • MainApplication 是应用程序类吗?那么这应该是一个上下文。制作一个新的 Fragment,还没有任何 Activity 可以获取
  • 好的。该类扩展了 Context,那为什么要从 Fragment 中获取 Activity?
  • 据我所知,这似乎是一个类似的帖子。 stackoverflow.com/questions/30692501/…
  • 我真的不知道你想在 UI 线程上运行什么。好像你正在使用 Couchbase Lite,我认为使用 RxJava 绑定异步代码
  • 好吧,不过,我不会在适配器中放置线程。我一直想自己学习couchbase lite,所以不能提供任何提示。无论如何,您的适配器只需要一个上下文,而不是一个应用程序。如果您在 UI 线程上更新适配器时遇到问题,请将查询移至包含适配器的 Activity

标签: java android android-fragments dependency-injection dagger-2


【解决方案1】:

您可以使用 getActivity(),它返回与片段关联的活动。
Activity 是一个上下文(因为 Activity 扩展了 Context)。
这是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
    ...

【讨论】:

  • 你真的不需要静态上下文变量。 getActivity() 随时可以使用
  • 所以基本上,我会在我的 provideMyAdapter 方法中使用 MyFragment.mContext,并且在初始化 mContext 之前不要注入我的适配器?
  • 你的provideMyAdapter没问题(传入context),有时间可以打个结,这样简单高效。
  • 我的意思是使用静态上下文,这不会导致上下文的保留时间超过应有的时间吗?虽然,在我的具体情况下,我的片段与应用程序一样长,所以它可能无关紧要
【解决方案2】:

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

【讨论】:

  • 抱歉,您能否详细说明一下“创建一些范围”部分?我的 AppModule 类只在我的 MainApplication 类中初始化一次,它只执行一次。我的应用程序只有一个主要活动和一个主要片段,一切都发生在那个片段中。在 AppModule 中初始化我的片段会导致一些不需要的结果吗?
  • 不,如果你只有一个片段,那么你不会有任何问题。但是如果碎片数量如此之大,那么您不应该在应用程序启动时创建所有碎片
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
相关资源
最近更新 更多