简体   繁体   中英

Android app crashes when back button is pressed

I have run into an annoying crash in my app when the user clicks the back button.

In my app, i have 3 relevant activities:

  • MainActivity: shows a list of Persons
  • PersonActivity: shows a list of all the Payments of a Person
  • AddPaymentActivity: has input elements to add a Payment to a Person

From MainActivity the user can either tap on a Person's name in the list to go to PersonActivity or use a "+" button next to the Person's name and jump directly into AddPaymentActivity. In PersonActivity there is a "+" button that leads to AddPaymentActivity, too.

The Perons data is stored in a Java Person class that implements the Serializable interface. When starting an Activty i forward the Person Object via

intent.putExtra(MainActivity.PERSON_MESSAGE, person);

When i go from MainActivity directly into AddPaymentActivity (via "+"), the back button works fine. If i however use start AddPaymentActivity from PersonActivity, my application crashes with a null pointer exception.

Using the debugger i noticed that PersonActivity.onCreate() is called (again?) when the back button is pressed. Why does this happen when going back form AddPaymentActivity to PersonActivity? And why does that NOT happen when going back from AddPaymentActivity to MainActivity? What can i do to fix the problem?

Stack trace:

01-13 10:11:01.423: E/AndroidRuntime(1022): FATAL EXCEPTION: main
01-13 10:11:01.423: E/AndroidRuntime(1022): Process: de.emteg.cashsplit, PID: 1022
01-13 10:11:01.423: E/AndroidRuntime(1022): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.emteg.cashsplit/de.emteg.cashsplit.PersonActivity}: java.lang.NullPointerException
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2176)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.ActivityThread.access$700(ActivityThread.java:135)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.os.Handler.dispatchMessage(Handler.java:102)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.os.Looper.loop(Looper.java:137)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.ActivityThread.main(ActivityThread.java:4998)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at java.lang.reflect.Method.invokeNative(Native Method)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at java.lang.reflect.Method.invoke(Method.java:515)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at dalvik.system.NativeStart.main(Native Method)
01-13 10:11:01.423: E/AndroidRuntime(1022): Caused by: java.lang.NullPointerException
01-13 10:11:01.423: E/AndroidRuntime(1022):     at java.math.BigDecimal.<init>(BigDecimal.java:425)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at de.emteg.cashsplit.PersonActivity.onCreate(PersonActivity.java:37)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.Activity.performCreate(Activity.java:5243)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-13 10:11:01.423: E/AndroidRuntime(1022):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
01-13 10:11:01.423: E/AndroidRuntime(1022):     ... 11 more

MainActivity.onCreate:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_overview);

    persons = new ArrayList<Person>();

            // Populate list with some test person objects
    Person p = new Person("Frank");
    p.getPayments().add(new Payment("test1", new BigDecimal(5.7)));
    persons.add(p);

    p = new Person("Peter");
    persons.add(p);

    ListView list = (ListView) findViewById(R.id.listView1);
    PersonAdapter adapter = new PersonAdapter();
    list.setAdapter(adapter);
    // output....
}

PersonActivity.onCreate():

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_person);

    Intent intent = getIntent();        
    this.person = (Person) intent.getSerializableExtra(MainActivity.PERSON_MESSAGE);
    this.share = new BigDecimal(intent.getStringExtra(MainActivity.SHARE_MESSAGE));
    this.totalSum = new BigDecimal(intent.getStringExtra(MainActivity.SUM_MESSAGE));
    this.diff = person.getSum().subtract(share);

    setupActionBar();

    // output...
}

AddPaymentActivty.onCreate():

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_payment);
    // Show the Up button in the action bar.
    setupActionBar();

    Intent intent = getIntent();

    this.person = (Person) intent.getSerializableExtra(MainActivity.PERSON_MESSAGE);

    if (intent.hasExtra(MainActivity.PAYMENT_MESSAGE)) {
        this.payment = (Payment) intent.getSerializableExtra(MainActivity.PAYMENT_MESSAGE);
        // output....
    } else {
        this.payment = null;
        // output...
    }

}

Your problem is in one of those 2 lines :

this.share = new BigDecimal(intent.getStringExtra(OverviewActivity.SHARE_MESSAGE));
this.totalSum = new BigDecimal(intent.getStringExtra(OverviewActivity.SUM_MESSAGE));

It seems that one of your 2 getStringExtra return null.

It must be because of a null pointer exception which causes your app to crash.

First, check if in your PersonActivity needs a value that is not passed/set when back button is pressed from your AddPaymentActivity.

You may also override the onResume() function, it will be called when back button is pressed.

Check that you have not added finish(); after your intent.The intent/activity you wish to return to from the previous activity,when adding this intent to the parent activity,make sure that the parent activity invoking this intent does not have finish();.for example:

Main Activity calling payment activity:

Intent d = new Intent(getApplicationContext(),
                PaymentActivity.class);
        startActivity(d);
        finish();***//remove this***
        return true;

if you tell the activity calling another activity to finish(),this basically means that activity called can neevr return to the previous activity, therefore this below is correct: //finish();has been removed

 Intent d = new Intent(getApplicationContext(),
                PaymentActivity.class);
        startActivity(d);
        return true;

The next thing you need to do is make sure your manifest has parent activity added to the activities.

Eg:

<activity
        android:name=".PaymentActivity"
        android:label="@string/paymentlabel"
        android:parentActivityName=".PaymentActivity" />

And in your Payment Activity onCreate add,the following:

assert getSupportActionBar() != null;***> //this tells the application that ActionBar is not null and therefore dont call an java null exceptions and crash the activity

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM