DialogFragment(支持v4)崩溃应用程序(NPE)

时间:2015-05-11 08:07:39

标签: java android android-dialogfragment dialogfragment

我已经在StackOverflow上检查过很多相同的问题,但我没有找到解决问题的方法。
DialogFragment中,我调用AsyncTask方法,当从服务器收到结果时,我启动了另一个DialogFragment
以下是我用来启动DialogFragment的代码:

public class RequesterConfirmRent extends DialogFragment {

// Called from onPostExecute() in AsyncTask class.
public void onPostComputeAmountToPay(JSONArray array){
        double amountToPay = 0.0;
        String ownerName = "";
        try{
            if(!array.getJSONObject(0).getBoolean("success"))
                Log.e("Error", "Error with JSON received");
            else {
                amountToPay = array.getJSONObject(1).getDouble("amountToPay");
                ownerName   = array.getJSONObject(2).getString("ownerName");
            }
        }catch(JSONException e){
            Log.e(e.getClass().getName(), "JSONException", e);
        }

        // Create and show the DialogFragment
        Paiement p = new Paiement();
        Bundle bdl = new Bundle();
        bdl.putString("ownerName", ownerName);
        bdl.putDouble("amountToPay", amountToPay);
        p.setArguments(bdl);

        // Buggy line (NPE)
        p.show(getFragmentManager(), "4554");
    }
}

以下是我尝试显示的DialogFragment的代码:

public class Paiement extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        if(getDialog() == null)
            super.setShowsDialog(false);
        Dialog dialog =  super.onCreateDialog(savedInstanceState);
        dialog.setTitle("Synthesis of your rent");
        return dialog;
    }

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

   private void init(View v){// Bla bla ...}
}

当我调用.show()方法时,我总是得到一个NullPointerException?

我做错了什么?

非常感谢你的帮助!

编辑1 :根据要求,这是LogCat

  

05-11 09:58:34.470 31384-31384 / com.example.celien.drivemycar   E / AndroidRuntime:致命异常:主要       显示java.lang.NullPointerException               在android.support.v4.app.DialogFragment.show(DialogFragment.java:136)               at com.example.celien.drivemycar.fragment.RequesterConfirmRent.onPostComputeAmountToPay(RequesterConfirmRent.java:148)

编辑2 我修改了这样的代码,看起来getFragmentManager()为null。为什么呢?

        Paiement p = new Paiement();
        Bundle bdl = new Bundle();
        bdl.putString("ownerName", ownerName);
        bdl.putDouble("amountToPay", amountToPay);
        p.setArguments(bdl);
        // BUGGY LINE
        android.support.v4.app.FragmentManager f = getFragmentManager();
        if(p == null)
            Log.d("Exception ", "p is null");
        if(f == null)
            Log.d("Exception ", "f is null");

        try {
            p.show(f, "4554");
        }catch(NullPointerException e){
            Log.d("Exception  ", e.toString());
        }

编辑3: 有一些新鲜的信息!
为避免创建此对话框,我在ToastToast.makeText(this.getActivity(), "You have to pay "+amountToPay+"e to " +ownerName, Toast.LENGTH_LONG).show();中显示数据,并获得 NPE 但是如果我使用Log系统,一切都很好:

Log.d("Rcvd ", String.valueOf(amountToPay));
Log.d("Rcvd ", ownerName);

那么,为什么我的活动为空?

1 个答案:

答案 0 :(得分:2)

如果您在拨打p.show()而非p.setArguments()时收到NPE,可能p可以,但show来电内的某些内容不是吗?

可能需要解决的问题是您使用FragmentManager的支持版本进行getFragmentManager()调用。请尝试使用getSupportFragmentManager()。在需要时它将回归到正确的那个。 另一方面,您正在呼叫android.support.v4.app.FragmentManager。如果您手动添加了软件包,那很奇怪,那么您的IDE可能会为您做到这一点。您可以尝试删除FragmentManager后面的包,并希望代码符合非支持标准框架。可能只是对支持库的这个引用已经完成,因此删除包部分可以解决问题。

我的建议:在应用中,在定义活动和片段时,始终坚持标准框架或支持库。因此,请确保您创建的ActivityFragment 扩展了适当的支持(或标准框架)版本。混合它们最终会导致意外崩溃。

另外,正如我的一条评论中所提到的, AsyncTask即使在您的片段分离后也可以自由运行,因此该片段不再正确引用任何活动。 This answer告诉您通过查看isDetached()来检查片段是否已分离。检查他的答案。他正在讨论使用Loader而非AsyncTask s或将AsyncTask移至活动,因此活动始终可用。展望未来,Loader是最好的选择(因为它是AsyncTask的自然演变),看着现在,尝试将AsyncTask移动到共同点活性。