【问题标题】:Dagger2 crashing on setText calling ViewModelDagger2 在调用 ViewModel 的 setText 上崩溃
【发布时间】:2019-04-10 05:57:47
【问题描述】:

应用程序构建但在运行时因空对象引用而崩溃。一直在尝试调试它但找不到错误但我知道如果我删除 textview 上的 setText 调用方法来检索字符串然后通过片段显示在 MainActivity 中(如果我删除它不会崩溃)这让我相信我的空对象与我没有实例化视图模型的方式有关。不确定如何执行此操作。

尝试从堆栈跟踪中删除和定位 bufg,该错误指出空对象引用在片段中的 onActivityCreated 中,但 Dagger 生成代码这是我迷失的地方,就好像我不运行它构建并且显示没有编译时错误一样。

public class HomeFragment extends Fragment {
@Inject
HomeViewModel homeViewModel;
TextView tvFrag;

public HomeFragment() {
}


@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v= inflater.inflate(R.layout.fragment_home, container, false);
    return v;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    tvFrag = getActivity().findViewById(R.id.tv_frag);
    tvFrag.setText(homeViewModel.getConnection()); //HERE
}

}

@FragmentScope
public class HomeViewModel extends ViewModel {


private DatabaseService databaseService;
private NetworkService networkService;
private NetworkHelper networkHelper;

@Inject
public HomeViewModel(DatabaseService ds, NetworkService ns, NetworkHelper nh){
    this.databaseService = ds;
    this.networkService = ns;
    this.networkHelper = nh;

}
public String getConnection(){
    return "Ben Mohammad Connected";
}

}

GitHub 链接 - https://github.com/BenMohammad/LearnDagger-STAGE_2-with-dagger-better

应该在viewModel中调用getConnection()方法,获取一个字符串并显示在已经添加到MainActivity的fragment上。

谢谢

【问题讨论】:

  • 鉴于代码原样,我想说它很可能是为空的 viewModel。你在什么时候用匕首注入片段?
  • 是的,你是对的 Fred 我已经上传了 stackTrace 我不明白如何使用 Dagger 实例化视图模型......
  • 你使用的是 dagger-android 还是只是 dagger?
  • 实现 "com.google.dagger:dagger:2.21" annotationProcessor "com.google.dagger:dagger-compiler:2.21"

标签: java android dagger android-viewmodel


【解决方案1】:

您尚未在该视图中执行依赖注入。可能是:

AndroidSupportInjection.inject(this);

或:

((YourApplicationClass) getActivity().getApplication()).getApplicationComponent().inject(this);

(如果您没有使用 Dagger for Android ),在您的 onCreate 方法中。

在这种情况下,Dagger 会知道它有一些依赖项要注入到该片段中,在您的情况下是 HomeViewModel。否则,HomeViewModel 仍然为空,直到您执行 DI

【讨论】:

  • 到达那里,“FragmentActivity 无法转换为 MyApplication”现在它不会构建 Dagger 令人困惑,我需要学习这一点。这是我的片段github.com/BenMohammad/LearnDagger-STAGE_2-with-dagger-better/…
  • 好的,以上只是在你的视图中如何执行依赖注入的一个例子。只需在那里执行您的 DI 并完成。
【解决方案2】:

您没有在片段中注入HomeViewModel。 尝试在您的onCreate 方法中使用AndroidSupportInjection.inject(this);。 方法应该是这样的

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AndroidSupportInjection.inject(this);
}

【讨论】:

  • 你是对的我没有我不知道怎么做,我已经实现了我相当确定它必须是我使用 Dagger 的方式,因为每个人都缺少一些东西告诉我更改将 setText 放在 onCreateView 或 onViewCreated 等的位置,这些都不起作用。我尝试了 Android SupportInjection 并没有构建我将推送到 github。任何帮助或指针表示赞赏。谢谢
  • 您的代码有很多需要更改的地方。要制作AndroidSupportInject.inject(this),您需要将库添加到您的 gradle。 implementation "com.google.dagger:dagger-android-support:$dagger2Version" 如果您使用支持库,则需要在您的 graddle 中添加 annotationProcessor。 annotationProcessor "com.google.dagger:dagger-android-processor:$dagger2Version"
【解决方案3】:

好吧,我认为答案(包括我的)比你更困惑。

ViewModel 必须像这样初始化(我不知道你的模块中有什么,但这是正确的方法):在onCreate 方法中:

HomeViewModel homeviewModel = ViewModelProviders.of(this).get(HomeViewModel.class);

如果您需要将依赖项传递给您的 viewmodel ,请使用 ViewModel Factory 。谷歌自己或只是参考this link

【讨论】:

    【解决方案4】:

    您试图在父 Activity 中找到 tv_frag 而不是当前片段。

    改为:

    tvFrag = getView().findViewById(R.id.tv_frag);
    tvFrag.setText(homeViewModel.getConnection());
    

    【讨论】:

    • 之前试过这个,显然没有工作仍然崩溃我需要提供更多细节。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多