【问题标题】:Android NullPointerExpection on pressing Back with FragmentsAndroid NullPointerException 在使用 Fragments 按下 Back 时
【发布时间】:2014-01-28 14:07:04
【问题描述】:

我是 Fragments 的新手,在按回某些 Fragments 时遇到问题。

MainActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.drawer_main);

    //Fragments are added programmatically here...
    LoginFragment fragment = new LoginFragment();
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.add(R.id.content_frame, fragment);
    transaction.commit();       
}

      @Override
  public void onBackPressed() {   
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();

    Fragment curFrag;
    curFrag = (Fragment) fm.findFragmentByTag("keuzen");
    if (curFrag.isVisible() || curFrag.getTag() == "keuzen") {
        Toast.makeText(getBaseContext(), "much keuzen", Toast.LENGTH_SHORT).show();
        //keuzenFrag = null;
    } 

    //Fragment curFrag = ((FragmentManager) fm.getFragments()).findFragmentByTag("single");
    curFrag = (Fragment) fm.findFragmentByTag("single");
    if (curFrag.isVisible()) {
        Toast.makeText(getBaseContext(), "very single", Toast.LENGTH_SHORT).show();
    }
}

我没有对 Fragments 中的 onBackPressed 做任何事情。 奇怪的是,只有一个带有异步代码的片段,当我点击后退按钮时它崩溃了。 但是当我转到另一个 Fragment,然后返回到带有异步代码的 Fragment,然后按返回按钮时,它崩溃了。

片段中的异步代码Fragment2

/**
         * Async task class to get json by making HTTP call
         * */
        private class GetKeuzes extends AsyncTask<Void, Void, Void> {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                // Showing progress dialog
                pDialog = new ProgressDialog(getActivity()); //KeuzenActivity.this
                pDialog.setMessage("Laden...");
                pDialog.setCancelable(false);
                pDialog.show();

            }

            @Override
            protected Void doInBackground(Void... arg0) {
                // Creating service handler class instance
                ServiceHandler sh = new ServiceHandler();

                // Making a request to url and getting response
                String jsonStr = sh.makeServiceCall(url , ServiceHandler.GET);

                Log.d("Response: ", "> " + jsonStr);

                if (jsonStr != null) {
                    try {
                        JSONObject jsonObj = new JSONObject(jsonStr);

                        // Getting JSON Array node
                        docent_opties = jsonObj.getJSONArray("docent_opties");

                        // loop door alle keuzes heen uit de JSON
                        for (int i = 0; i < docent_opties.length(); i++) {
                            JSONObject c = docent_opties.getJSONObject(i);

                            naam_cursus = c.getString(TB_naam_cursus);
                            naam_locatie = c.getString(TB_naam_locatie);
                            datum_vol = c.getString(TB_datum_vol);
                            naam_dagdeel = c.getString(TB_naam_dagdeel);

                            // Phone node is JSON Object
                            //JSONObject phone = c.getJSONObject(TAG_PHONE);
                            //String mobile = phone.getString(TAG_PHONE_MOBILE);
                            //String home = phone.getString(TAG_PHONE_HOME);
                            //String office = phone.getString(TAG_PHONE_OFFICE);

                            // temp HashMap voor enkele keuze
                            HashMap<String, String> keuze = new HashMap<String, String>();

                            // adding each child node to HashMap key => value
                            keuze.put(TB_naam_cursus, naam_cursus);
                            keuze.put(TB_naam_locatie, naam_locatie);
                            keuze.put(TB_datum_vol, datum_vol);
                            keuze.put(TB_naam_dagdeel, naam_dagdeel);
                            keuze.put("datum_dagdeel", datum_vol + ", '" + naam_dagdeel + "'");

                            keuzenList.add(keuze);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else {
                    Log.e("ServiceHandler", "Gegevens ophalen via de url is mislukt");
                }

                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                // Dismiss the progress dialog
                if (pDialog.isShowing())
                    pDialog.dismiss();
                /**
                 * Updating parsed JSON data into ListView
                 * */
                ListAdapter adapter = new SimpleAdapter(
                        getActivity(), keuzenList,
                        R.layout.list_item, new String[] { TB_naam_cursus,  TB_naam_locatie, "datum_dagdeel" }, new int[]
                                { R.id.naamcursus, R.id.locatie, R.id.datum });
                setListAdapter(adapter);

            }
        }

但是,即使从 Fragment 中删除 Async 代码,仍然会出现同样的问题... 所以它不应该是异步代码。

这是日志: http://pastebin.com/J5VhhCLG

【问题讨论】:

    标签: android asynchronous android-fragments nullpointerexception


    【解决方案1】:

    尝试使用 FragmentManager 的 findFragmentById() 或 findFragmentByTag() 方法,片段标签是您的问题。 你是如何添加片段的:

    FragmentTransaction.add(int containerViewId, Fragment fragment, String tag) ? 请记住片段事务是异步运行的,请确保已设置标签。

    是的,它的“发现”没有得到,对此感到抱歉。

    【讨论】:

    • getFragmentByTag() 似乎不存在?我能找到的最接近的是:findFragmentByTag()。这就是我添加片段的方式:pastebin.com/Az2cjcVQ
    【解决方案2】:

    事实是我试图从一个片段中打开另一个片段。

    你应该做的是在你的 MainActivity 中创建一个函数:

    public void openSesame(Bundle bundle) {
        //Method2: pass data to fragment directly.
        android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
        KeuzenFragment keuzenFragment = new KeuzenFragment();
        keuzenFragment.setArguments(bundle);
        android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.content_frame, keuzenFragment, "keuzen").addToBackStack("keuzen");
        transaction.remove(fragment1);
        transaction.commit();
    }
    

    您可能想稍微改变一下,以便在重载中与 Fragments 一起使用。 但是该功能在您的 MainActivity 中。 像这样从 MainActivity 调用该函数:

    ((MainActivity)getActivity()).openSesame(bundle);
    

    完成。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      相关资源
      最近更新 更多