按下碎片后面的Android NullPointerExpection

时间:2014-01-28 14:07:05

标签: android asynchronous android-fragments nullpointerexception

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

我没有对碎片中的onBackPressed做任何事情。 奇怪的是,只有一个片段带有异步代码,当我按下后退按钮时会崩溃。 但是当我转到其他片段,然后使用异步代码返回片段,然后按后退按钮时,它会崩溃。

片段中的异步代码 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代码,仍会出现同样的问题...... 所以它不应该是异步代码。

这是logcat: http://pastebin.com/J5VhhCLG

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

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

您应该做的是在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);

完成。 :)