简体   繁体   中英

What differs Up Button to Back Button? And how to make Up Button work like Back Button?

In terms of how each button treat the activities? What are the differences?

I have 3 activities (let's call them A, B, and C). A is B's parent and B is C's parent, and one intent take a extra to the the next activity. I go from A to B and then B to C. When I try to go back using Up Button, the app crashes, and that's because it tries to get a info from the extra in the intent.

But when I use Back Button, it works (???) and I don't know why.

I tried to make Up Button work like Back Button, doing the following:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.home:
            onBackPressed();
            break;
    }
    return super.onOptionsItemSelected(item);
}

and also tried using NavUtils.navigateUpFromSameTask(this) but it's not working either. How can I solve it?

Edit: error Log

2019-01-09 03:45:43.468 29326-29326/com.jvponte.maosdadasv1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.jvponte.maosdadasv1, PID: 29326
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jvponte.maosdadasv1/com.jvponte.maosdadasv1.UserActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.jvponte.maosdadasv1.User.getUsername()' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:169)
    at android.app.ActivityThread.main(ActivityThread.java:6568)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.jvponte.maosdadasv1.User.getUsername()' on a null object reference
    at com.jvponte.maosdadasv1.UserActivity.onCreate(UserActivity.java:67)
    at android.app.Activity.performCreate(Activity.java:7016)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
    at android.os.Handler.dispatchMessage(Handler.java:105) 
    at android.os.Looper.loop(Looper.java:169) 
    at android.app.ActivityThread.main(ActivityThread.java:6568) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

Edit: some more code I have this in onCreate() on my activity B ( UserActivity ). The intent extra is added on activity A

    Intent intent = getIntent();

    if(intent.hasExtra("clickedUser")){
        mOtherUser = intent.getParcelableExtra("clickedUser");
    }
    if(intent.hasExtra("loggedUser")){
        mLoggedUser = intent.getParcelableExtra("loggedUser");
    }

    /.../

    mUsernameTV.setText(mOtherUser.getUsername());
    mUserInfoTV.setText(mOtherUser.getUserInfo());

Here I call activity C ( ChatActivity )

Intent intent = new Intent(UserActivity.this, ChatActivity.class);
intent.putExtra("loggedUser", mLoggedUser);
intent.putExtra("clickedUser", mOtherUser);
startActivityForResult(intent, RC_CHAT);

In ChatActivity onCreate() I have this

    Intent intent = getIntent();
    if (intent.hasExtra("clickedUser")){
        otherUser = intent.getParcelableExtra("clickedUser");
        otherUserId = otherUser.getUid();
        otherUserName = otherUser.getUsername();
    }
    if (intent.hasExtra("loggedUser")){
        loggedUser = intent.getParcelableExtra("loggedUser");
        loggedUserId = loggedUser.getUid();
    }

The error is problably this loggedUser and otherUser extra not being correctly managed. The weirdest thing is that using Back Button WORKS, while setting Up Button to work like Back Button doesn't

Try to change your code like following to simulate back button behavior:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case android.R.id.home:
            onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

The main difference between up and back is not visible when you use the app regularly.

But for example, if you open a detail activity from a link, the app opens with just the detail activity. Now if you press on the back button on the toolbar, the following can happen:

  • Up navigation means, that you are going up in the hierarchy, so to the parent of the detail activity, like a home activity.
  • Back navigation means, that you go back to where you were before, so that would mean going back to the last used app, like the browser you opened the link from.

It is up to you, how you implement this, so you have to decide what would be more logical or useful to the users of your app.

and also tried using NavUtils.navigateUpFromSameTask(this) but it's not working either. How can I solve it?

This is probably because you have not defined a parent activity for the activity you are currently in.

Have a look at the tutorial (especially the section Specify Parent ), where everything is described in detail about up navigation.


Edit after you provided the stack trace:

So up navigation works for you, only the activity you are navigating to expects some kind of user in its onCreate(...) method. You have to make sure that you provide all data to the parent activity.

If you provide data via intents, you can use the following code for opening the parent:

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    TaskStackBuilder.create(this)
        .addNextIntentWithParentStack(upIntent)
        .startActivities();
} else {
    NavUtils.navigateUpTo(this, upIntent);
}

I just removed the parent relation between B and C and used the code onOptionSelected() that I posted and it worked. Even when using that, making BC's parent was making it crash.

I still don't know why using Back Button works and Up Button doesn't, but it fixed the problem. Thanks everyone who tried to help

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