0

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

João Vítor
  • 11
  • 1
  • 7
  • 1
    are you getting error when you say it does't work? can you share your log if there is an error! :) – Anmol Jan 09 '19 at 06:34
  • @Anmol Ye, I am getting an error. I don't think it will help much cause it's a little bit specific. When I start the B activity, I get an extra from the intent created in A, and get a information from it. Since I am coming from activity C, I think this extra intent information is lost and I get a NullPointerException (and I don't know why it doesn't happen when I use Back Button instead). Anyway, I will add the log message :) – João Vítor Jan 09 '19 at 06:49
  • this is not the back problem, don't finish the activity and I think you finished activity than previous all activities loss their values and `getUsername()` is null. – Farhana Naaz Ansari Jan 09 '19 at 06:53
  • @farhana I had forgotten to finish() B activity as I start C. Now it's partially working, but from C it's going back to A (and B is the C's parent, and I double checked it) – João Vítor Jan 09 '19 at 07:07
  • @JoãoVítor don't add finish() if you finish activity then you will lose all value on previous activity. – Farhana Naaz Ansari Jan 09 '19 at 07:09
  • @farhana just noticed that hahah actually I didn't really get what you said in your last comment – João Vítor Jan 09 '19 at 07:13
  • @JoãoVítor have you fixed problem? – Farhana Naaz Ansari Jan 09 '19 at 07:38
  • @farhana no, I'm still stuck on that – João Vítor Jan 09 '19 at 08:29
  • @JoãoVítor still you are getting the same error for better approach it is better to upload more code. – Farhana Naaz Ansari Jan 09 '19 at 08:51
  • @farhana I added some more code. Check if it helps to understand the problem please – João Vítor Jan 09 '19 at 09:15
  • you are starting the activity by using `startActivityForResult` if this is used then you need to implement 'onActivityResult' to catch result on that activity where you are using 'startActivityForResult' and according to your `error log` your are getting username name null. so you need to check where you are getting the object of model classs for ` getUsername` – Farhana Naaz Ansari Jan 09 '19 at 09:23
  • @farhana I try to get that from the intent, but the extra is added in activity A, and I don't know how to get it back when coming from activity C. When using back button everything is working fine, but not when using up button. I tried using startActivityForResult to get it back on onActivityResult, but it didn't work either – João Vítor Jan 09 '19 at 17:54

3 Answers3

0

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);
}
aminography
  • 21,986
  • 13
  • 70
  • 74
  • I added the error log on the end of the question :) – João Vítor Jan 09 '19 at 06:50
  • It says that `User` instance in `UserActivity` is null. I think the problem is not related to back button,... Please share parts of code from `UserActivity`. – aminography Jan 09 '19 at 06:54
  • I don't think it will help much cause it's a little bit specific. When I start the B activity, I get an extra from the intent created in A, and get a information from it. Since I am coming from activity C, I think this extra intent information is lost and I get a NullPointerException (and I don't know why it doesn't happen when I use Back Button instead). – João Vítor Jan 09 '19 at 07:14
0

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);
}
Daniel Zolnai
  • 16,487
  • 7
  • 59
  • 71
  • Zolnei That's what I supposed, but in this case I always start activity C from activity B, meaning (I guess) that Up and Back buttons should work the same, but it doesn't. And I did have defined the B as C's parent in the manifest :( – João Vítor Jan 09 '19 at 07:00
  • Have a look at UserActivity.java line 67, your User object is null there. Check why that can happen, you probably try to get it from the intent, which does not have a user object. – Daniel Zolnai Jan 09 '19 at 07:01
  • Ye, I try to get that from the intent, but the extra is added in activity A, and I don't know how to get it back when coming from activity C. When using back button everything is working fine, but not when using up button – João Vítor Jan 09 '19 at 07:10
  • I didn't get what this code is meant to do. When I added it when I tried to go from A to B it kept returning to A. – João Vítor Jan 09 '19 at 07:17
  • If you have it in your detail activity, you can do up navigation by starting parent activity with intent (including the user data), and finishing detail activity. – Daniel Zolnai Jan 09 '19 at 07:18
  • Am I supposed to add it just the way it is? I did it and it keeps returning to its parent – João Vítor Jan 09 '19 at 09:16
  • Not necessarily. As I have said earlier, fixing the crash will fix your issue. You should make sure that upIntent has the clickUser property with the user data, or rewrite UserActivity that it works without clickUser – Daniel Zolnai Jan 09 '19 at 09:54
0

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 B C'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

João Vítor
  • 11
  • 1
  • 7