Nullpointer at Upnavigation android

212 Views Asked by At

I would like to send two extras via intent, when upnavigation at actionbar is clicked. At the manifest parent activity is declared, at OnCreate at the second activity getActionBar().setDisplayHomeAsUpEnabled(true); is set. But the parent activity needs an intent value to work (citySave). I´ve tried a lot, but I don´t get it working, that the upnavigation sends intent values to the parent activity (R.id.home).

I´ven´t added the whole code from second activity, because it would be too much signs. I use at second activity 2 fragments, which are defined static. I don´t know, if this has anything to do with the problem.

Second activity:

public class RouteView extends ActionBarActivity {

    Integer citySave;
    String cityTitle;
    Integer routeSave;
    String routeTitel;
    private static int NUM_ITEMS = 2;
    SectionsPagerAdapter mSectionsPagerAdapter;
    ListView listView;
    ArrayList<RowItem> pois;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_route_view);
        Bundle b = getIntent().getExtras();
        citySave = b.getInt("stadt");
        cityTitle = b.getString("titel_stadt");
        routeSave = b.getInt("route");
        routeTitel = b.getString("titel_route");
        b.putString("titel_route",routeTitel);
        b.putInt("route", routeSave);
        getActionBar().setDisplayHomeAsUpEnabled(true);
        //RouteItemFragment fragobj = new RouteItemFragment();
        //fragobj.setArguments(b);

        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        setTitle("Route:" + " " + routeTitel);


public void onBackPressed() {
        super.onBackPressed();
        Intent intent = new Intent();
        intent.setClass(RouteView.this, RouteChooseActivity.class);
        Bundle b = new Bundle();
        b.putInt("stadt", citySave);
        b.putString("titel_stadt", cityTitle);
        intent.putExtras(b);
        startActivity(intent);
        finish();
    }

    public void onPause() {
        super.onPause();
        Bundle b = new Bundle();
        b.putInt("stadt", citySave);
        b.putInt("route", routeSave);
        b.putString("route_titel",routeTitel);
        finish();
    }

    public void onResume() {
        super.onResume();

        Bundle b = getIntent().getExtras();
        citySave = b.getInt("stadt");
        routeSave = b.getInt("route");
        routeTitel = b.getString("route_titel");

    }

    public void onStop() {
        super.onStop();
        finish();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                Intent upIntent = NavUtils.getParentActivityIntent(this);
                Bundle b = new Bundle();
                b.putInt("stadt", citySave);
                b.putString("titel_stadt", cityTitle);
                upIntent.putExtras(b);
                //startActivity(upIntent);
                return true;
            case R.id.action_stadt:
                setContentView(R.layout.activity_stadt);
                Intent stadt = new Intent(RouteView.this, StadtActivity.class);
                startActivity(stadt);
                return true;
            case R.id.action_route:
                setContentView(R.layout.activity_route_choose);
                Intent route = new Intent(RouteView.this, RouteChooseActivity.class);
                route.putExtra("stadt", citySave);
                route.putExtra("titel_stadt", cityTitle);
                startActivity(route);
                return true;
            case R.id.action_help:
                setContentView(R.layout.activity_help);
                Intent help = new Intent(RouteView.this, Help.class);
                startActivity(help);
                return true;
            case R.id.action_exit:
                moveTaskToBack(true);
                System.exit(0);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

}

Parent activity:

    public class RouteChooseActivity extends ActionBarActivity implements OnItemClickListener {

        Integer citySave;
        Integer routeSave;
        String cityTitle;
        ListView listView;
        List<RowItem> cities;
        CityParser parser = new CityParser();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_route_choose);
            Bundle b = getIntent().getExtras();
            citySave = b.getInt("stadt");
            cityTitle = b.getString("titel_stadt");
            TextView headingRoute = (TextView) findViewById(R.id.routeTitel);
            headingRoute.setText(String.format(getResources().getString(R.string.route_text)) + " " + cityTitle + " aus:");
            listView = (ListView) findViewById(R.id.listRoute);
   if (citySave.equals(1)) {
            try {
                cities = parser.parse(getAssets().open("route_passau.xml"));
                CityListViewAdapter adapter = new CityListViewAdapter(this, R.layout.row_items, (ArrayList<RowItem>) cities);
                Collections.sort(cities, new Comparator<RowItem>() {
                    public int compare(RowItem s1, RowItem s2) {
                        return s1.getTitle().compareTo(s2.getTitle());
                    }
                });
                listView.setAdapter(adapter);

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (citySave.equals(2)) {
            try {
                cities = parser.parse(getAssets().open("route_bamberg.xml"));
                CityListViewAdapter adapter = new CityListViewAdapter(this, R.layout.row_items, (ArrayList<RowItem>) cities);
                Collections.sort(cities, new Comparator<RowItem>() {
                    public int compare(RowItem s1, RowItem s2) {
                        return s1.getTitle().compareTo(s2.getTitle());
                    }
                });
                listView.setAdapter(adapter);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (citySave.equals(3)) {
            try {
                cities = parser.parse(getAssets().open("route_augsburg.xml"));
                CityListViewAdapter adapter = new CityListViewAdapter(this, R.layout.row_items, (ArrayList<RowItem>) cities);
                Collections.sort(cities, new Comparator<RowItem>() {
                    public int compare(RowItem s1, RowItem s2) {
                        return s1.getTitle().compareTo(s2.getTitle());
                    }
                });
                listView.setAdapter(adapter);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            try {
                TextView errorMessage = (TextView) findViewById(R.id.routeTitel);
                errorMessage.setText(R.string.errorroute);
            } catch (NullPointerException e) {
                Context context = getApplicationContext();
                CharSequence text = getResources().getString(R.string.errorroute);
                int duration = Toast.LENGTH_LONG;
                Toast toast = Toast.makeText(context, text, duration);
                toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
                toast.show();
            }
        }
        listView.setOnItemClickListener(this);

        final ActionBar actionBar = getSupportActionBar();
        setTitle("Routen in" + " " + cityTitle);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent intent = new Intent();
        intent.setClass(RouteChooseActivity.this, RouteView.class);
        RowItem cities = (RowItem) parent.getItemAtPosition(position);
        Bundle b = new Bundle();
        b.putInt("stadt", citySave);
        b.putString("titel_stadt", cityTitle);
        b.putInt("route", cities.getID());
        b.putString("titel_route", cities.getTitle());
        intent.putExtras(b);
        startActivity(intent);
    }

     @Override
protected void onSaveInstanceState (Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("stadt", citySave);
    outState.getString("titel_stadt", cityTitle);
}

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        // Restore UI state from the savedInstanceState.
        // This bundle has also been passed to onCreate.
        citySave = savedInstanceState.getInt("stadt");
        Log.i("debug", "saved data: " + citySave);
    }

    @Override
    public void onResume() {
        super.onResume();

            Bundle b = getIntent().getExtras();
            citySave = b.getInt("stadt");
            cityTitle = b.getString("titel_stadt");

    }

    @Override
    public void onPause() {
        super.onPause();
        Bundle b = new Bundle();
        b.putInt("stadt", citySave);
        b.putString("titel_stadt", cityTitle);
        unbindDrawables(findViewById(R.id.Bild));
        System.gc();
    }

    @Override
    public void onStop() {
        super.onStop();
        Bundle b = new Bundle();
        b.putInt("stadt", citySave);
        b.putString("titel_stadt", cityTitle);
        finish();
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        unbindDrawables(findViewById(R.id.Bild));
        System.gc();
    }

    @Override
    public void onRestart() {
        super.onRestart();
        Bundle b = getIntent().getExtras();
        citySave = b.getInt("stadt");
        cityTitle = b.getString("titel_stadt");
    }

    private void unbindDrawables(View view)
    {
        if (view.getBackground() != null)
        {
            view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup && !(view instanceof AdapterView))
        {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
            {
                unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
            ((ViewGroup) view).removeAllViews();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.route, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_stadt:
                setContentView(R.layout.activity_stadt);
                Intent stadt = new Intent(RouteChooseActivity.this, StadtActivity.class);
                startActivity(stadt);
                return true;
            case R.id.action_help:
                setContentView(R.layout.activity_help);
                Intent help = new Intent(RouteChooseActivity.this, Help.class);
                startActivity(help);
                return true;
            case R.id.action_exit:
                moveTaskToBack(true);
                System.exit(0);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

Logcat:

java.lang.RuntimeException: Unable to start activity ComponentInfo{de.cityknight.app/de.cityknight.app.RouteChooseActivity}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at de.cityknight.app.RouteChooseActivity.onCreate(RouteChooseActivity.java:44)
            at android.app.Activity.performCreate(Activity.java:5231)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)
2

There are 2 best solutions below

0
On

Correct answer found on StackOverflow: https://stackoverflow.com/a/17342137/3762248

"The "standard" behaviour for an android activity is, that a new instance of the activity is created, every time there is a new intent for this activity (see launchMode-docu here). Because of this your extras seem to be gone, if you call navigateUpTo.

In your case, I would advise to use

android:launchMode="singleTop"

for your parent activity in your AndroidManifest.xml. This way you will return to your existing activity (as long as it is on the top of the back stack of your task). This way your extras will be preserved.

I too, do not understand why this is not mentioned in the Google doc you cite, as this seems the behaviour one expects if using up-navigation."

6
On

Inside your Activity's onCreate() method, the Bundle will have this value: (from the official documentation)

If the activity is being re-initialized after previously being shut down then this Bundle contains the data it most recently supplied in onSaveInstanceState(Bundle). Note: Otherwise it is null.

It goes the same for your getIntent().getExtras(). So you should check this value to avoid NullPointerException.

Bundle b = getIntent().getExtras();
if (b != null) {
  citySave = b.getInt("stadt");
  cityTitle = b.getString("titel_stadt");
}