可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have 2 activities (A and B) in my android application and I use an intent to get from activity A to activity B. The use of parent_activity is enabled:
<activity
android:name=\".B\"
android:label=\"B\" >
<meta-data
android:name=\"android.support.PARENT_ACTIVITY\"
android:value=\"com.example.app_name.A\" />
</activity>
I also use a theme which provides an UP-button.
So after I called activity B I can use the UP-button to get back to the activity A. The problem is that the application seems to call the onCreate()-function of activity A again and this is not the behaviour I need. I need activity A to look the same way like it looked before I called activity B.
Is there a way to achieve this?
Thanks in advance
EDIT:
I didn\'t write any code to start activity B from activity A. I think it is autogenerated by eclipse.
Class B looks like:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
回答1:
You declared activity A with the standard launchMode
in the Android manifest. According to the documentation, that means the following:
The system always creates a new instance of the activity in the target
task and routes the intent to it.
Therefore, the system is forced to recreate activity A (i.e. calling onCreate
) even if the task stack is handled correctly.
To fix this problem you need to change the manifest, adding the following attribute to the A activity declaration:
android:launchMode=\"singleTop\"
Note: calling finish()
(as suggested as solution before) works only when you are completely sure that the activity B instance you are terminating lives on top of an instance of activity A. In more complex workflows (for instance, launching activity B from a notification) this might not be the case and you have to correctly launch activity A from B.
回答2:
Updated Answer: Up Navigation Design
You have to declare which activity is the appropriate parent for each activity. Doing so allows the system to facilitate navigation patterns such as Up because the system can determine the logical parent activity from the manifest file.
So for that you have to declare your parent Activity in tag Activity with attribute
android:parentActivityName
Like,
<!-- The main/home activity (it has no parent activity) -->
<activity
android:name=\"com.example.app_name.A\" ...>
...
</activity>
<!-- A child of the main activity -->
<activity
android:name=\".B\"
android:label=\"B\"
android:parentActivityName=\"com.example.app_name.A\" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name=\"android.support.PARENT_ACTIVITY\"
android:value=\"com.example.app_name.A\" />
</activity>
With the parent activity declared this way, you can navigate Up to the appropriate parent like below,
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar\'s Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
So When you call NavUtils.navigateUpFromSameTask(this);
this method, it finishes the current activity and starts (or resumes) the appropriate parent activity. If the target parent activity is in the task\'s back stack, it is brought forward as defined by FLAG_ACTIVITY_CLEAR_TOP
.
And to display Up button you have to declare setDisplayHomeAsUpEnabled():
@Override
public void onCreate(Bundle savedInstanceState) {
...
getActionBar().setDisplayHomeAsUpEnabled(true);
}
Old Answer: (Without Up Navigation, default Back Navigation)
It happen only if you are starting Activity A again from Activity B.
Using startActivity()
.
Instead of this from Activity A start Activity B using startActivityForResult()
and override onActivtyResult()
in Activity A.
Now in Activity B just call finish()
on button Up. So now you directed to Activity A\'s onActivityResult()
without creating of Activity A again..
回答3:
I had pretty much the same setup leading to the same unwanted behaviour. For me this worked:
adding the following attribute to an activity A in the Manifest.xml
of my app:
android:launchMode=\"singleTask\"
See this article for more explanation.
回答4:
Although an old question, here is another (imho the cleanest and best) solution as all the previous answeres didn\'t work for me since I deeplinked Activity B from a Widget.
public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
Log.v(logTag, \"Recreate back stack\");
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
} else {
NavUtils.navigateUpTo(this, upIntent);
}
}
[https://stackoverflow.com/a/31350642/570168 ]
But also see: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android
回答5:
A better way to achieve this is by using two things:
call:
NavUtils.navigateUpFromSameTask(this);
Now, in order for this to work, you need to have your manifest file state that activity A
has a parent activity B. The parent activity doesn\'t need anything. In version 4 and above you will get a nice back arrow with no additional effort (this can be done on lower versions as well with a little code, I\'ll put it below)
You can set this data in the manifest->application tab in the GUI (scroll down to the parent activity name, and put it by hand)
Support node:
if you wish to support version below version 4, you need to include metadata as well.
right click on the activity, add->meta data, name =android.support.PARENT_ACTIVITY and value = your.full.activity.name
to get the nice arrow in lower versions as well:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
please note you will need support library version 7 to get this all working, but it is well worth it!
回答6:
I tried android:launchMode=\"singleTask\"
, but it didn\'t help.
Worked for me using android:launchMode=\"singleInstance\"
回答7:
Adding to @LorenCK\'s answer, change
NavUtils.navigateUpFromSameTask(this);
to the code below if your activity can be initiated from another activity and this can become part of task started by some other app
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this)
.addNextIntentWithParentStack(upIntent)
.startActivities();
} else {
NavUtils.navigateUpTo(this, upIntent);
}
This will start a new task and start your Activity\'s parent Activity which you can define in Manifest like below of Min SDK version <= 15
<meta-data
android:name=\"android.support.PARENT_ACTIVITY\"
android:value=\"com.example.app_name.A\" />
Or using parentActivityName
if its > 15
回答8:
What worked for me was adding:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBackPressed() {
finish();
}
to TheRelevantActivity.java
and now it is working as expected
and yeah don\'t forget to add:
getSupportActionbar.setDisplayHomeAsUpEnabled(true);
in onCreate()
method
回答9:
I had a similar problem using android 5.0 with a bad parent activity name
<activity
android:name=\".DisplayMessageActivity\"
android:label=\"@string/title_activity_display_message\"
android:parentActivityName=\".MainActivity\" >
<meta-data
android:name=\"android.support.PARENT_ACTIVITY\"
android:value=\"com.example.myfirstapp.MainActivity\" />
</activity>
I removed the com.example.myfirstapp from the parent activity name and it worked properly
回答10:
Add to your activity manifest information with attribute
android:launchMode=\"singleTask\"
is working well for me
回答11:
In Java class :-
toolbar = (Toolbar) findViewById(R.id.apptool_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(\"Snapdeal\");
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
In Manifest :-
<activity
android:name=\".SubActivity\"
android:label=\"@string/title_activity_sub\"
android:theme=\"@style/AppTheme\" >
<meta-data android:name=\"android.support.PARENT_ACTIVITY\" android:value=\".MainActivity\"></meta-data>
</activity>
It will help you
回答12:
try this:
Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
intent = getIntent();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpTo(this,intent);
return true;
}
return super.onOptionsItemSelected(item);
}
回答13:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar\'s Up/Home button
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
like a Back press
回答14:
Going into my manifest and adding android:launchMode=\"singleTop\"
to the activity did the trick for me.
This specifically solved my issue because I didn\'t want Android to create a new instance of the previous activity after hitting the Up
button in the toolbar - I instead wanted to use the existing instance of the prior activity when I went up the navigation hierarchy.
Reference: android:launchMode
回答15:
Try this solution use NavUtils.navigateUpFromSameTask(this); in the child activity:
https://stackoverflow.com/a/49980835/7308789
回答16:
Use finish()
in activity for going back when in your click event.