快速更改底部导航应用程序崩溃

时间:2018-08-30 11:24:02

标签: android android-fragments retrofit bottomnavigationview

我具有片段导航和api调用改造

我打电话给loadFragment如下切换片段

private boolean loadFragment(Fragment fragment) {
        //switching fragment
        if (fragment != null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fragment_container, fragment)
                    .commit();
            return true;
        }
        return false;
    }

问题是,如果我开始随机单击并快速更改片段,则我的应用程序崩溃。当我检查logcat时,它在设置一些数据时显示NPE。

我的片段由以下方法组成

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_current, container, false);
    unbinder = ButterKnife.bind(this, view);
    context = getActivity();
    callCategoryAPI();
    return view;
}

callCategory()是单独控制器类中的api改造调用,并通过interface返回响应,然后设置数据。

所以我怀疑我的API返回响应(因为它是异步的),但是由于用户更改了片段(很快),因此视图不可用,因此视图不可用。

我已经尝试setuserVisibleHint并尝试了1200ms的块单击,还检查了是否创建了我的片段视图,如何停止此崩溃?并让改造呼叫依赖生命周期?

Logcat

  

在com.example.CurrentFragment $ 1.onApiSuccess(CurrentFragment.java:82)          在com.example.services.current_statement.CurrentStatementController $ 2.onResponse(CurrentStatementController.java:91)          在retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall $ 1 $ 1.run(ExecutorCallAdapterFactory.java:70)          在android.os.Handler.handleCallback(Handler.java:790)          在android.os.Handler.dispatchMessage(Handler.java:99)          在android.os.Looper.loop(Looper.java:171)          在android.app.ActivityThread.main(ActivityThread.java:6606)          在java.lang.reflect.Method.invoke(Method.java)          在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:518)          在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

     

-

     

致命异常:java.lang.NullPointerException:尝试调用   虚方法   android.widget.TextView.setText(java.lang.CharSequence)'上的null   对象参考          在com.example.fragment.statements.CurrentFragment $ 1.onApiSuccess(CurrentFragment.java:82)          在com.example.services.current_statement.CurrentStatementController $ 2.onResponse(CurrentStatementController.java:91)          在retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall $ 1 $ 1.run(ExecutorCallAdapterFactory.java:70)          在android.os.Handler.handleCallback(Handler.java:790)          在android.os.Handler.dispatchMessage(Handler.java:99)          在android.os.Looper.loop(Looper.java:171)          在android.app.ActivityThread.main(ActivityThread.java:6606)          在java.lang.reflect.Method.invoke(Method.java)          在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:518)          在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

8 个答案:

答案 0 :(得分:1)

签入片段

if(activity != null && isAdded){

 Perform your operation

}

答案 1 :(得分:1)

在片段中设置

 if(getActivity() != null && isAdded) {

 //do your operation

}

答案 2 :(得分:0)

这是问题所在

  

试图在空对象引用上调用虚拟方法'void android.widget.TextView.setText(java.lang.CharSequence)'

您想要将文本设置为null的textview。您应该首先检查您的textview不为空,像这样:

if (textview != null){
    textview.setText("mytext");
}

答案 3 :(得分:0)

使用下面的这个库来阻止活动,直到网络操作完成为止。

Spot Dialog

这就是我在给您展示的图像中用于我的应用程序的内容。

答案 4 :(得分:0)

我可能会迟到,但我希望我也能帮助其他开发人员,因为我也遇到了这个问题。只需在if-else内的isAdded()回调中以您的条件使用onResponse

ex:在您的onResponse回调中:

if (isAdded()){
  // success response
} else {
  if(isAdded()){
    // error response
  }
}

答案 5 :(得分:0)

在片段中设置

 if(activity != null && isAdded) {

  // perform your task

}

答案 6 :(得分:0)

代码适用于android中的kotlin:

TextView?.text

在这里?表示不为空

像上面的显示一样使用它

答案 7 :(得分:0)

如果快速更改导航抽屉菜单项,当前片段也将被新片段替换。 Android可以删除在主线程中运行的所有正在进行的计算。但是,如果像后台网络响应结果这样的繁重任务或处理程序延迟的任务引用了片段,则可以找到null,因为片段已经分离或被新片段代替。

因此,您只需检查一下,您的愿望片段是否仍在活动中添加,或者在最近出现的流程响应数据之前没有添加。

    if(frag.isAdded()){
        //lets process your delayed response data
    }