简体   繁体   中英

Pressing back button from one activity refreshes previous activity in stack

On pressing back button from child activity parent activity displays for a second and refreshes itself.

In child activity I have this code in java file

@Override
public void onBackPressed()
{

    Intent moveback =
            new Intent(ClassActivityEdit.this, ClassActivity.class);
    startActivity(moveback);
    finish();
}

ClassActivityEdit is child class. In manifest file code is as follows

<activity android:name=".ClassActivity"
        android:label="Class Activity">
        <intent-filter>
            <action android:name="com.teamtreehouse.oslist.ClassActivity" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <activity android:name=".ClassActivityEdit"
        android:label="Class Activity"
        android:noHistory="true">
        <intent-filter>
            <action android:name="com.teamtreehouse.oslist.ClassActivityEdit" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

On back button I just want the ClassActivity layout to be displayed without it being refreshed.

Edit: ClassActivityEdit doesnt extend ClassActivity . Its just that some button press in ClassActivity will result in opening ClassActivityEdit .

Edit2

the below code in ClassActivity starts ClassActivityEdit

public void editListener(View v) {
        Intent addNewClass =
                new Intent(ClassActivity.this, ClassActivityEdit.class);
        RelativeLayout buttonTableRow = (RelativeLayout) v.getParent();
        TextView getCourseID = (TextView) buttonTableRow.findViewById(R.id.courseNumberActivity);
        String courseIDString = getCourseID.getText().toString();
        Bundle bundle = new Bundle();

        //Add your data to bundle
        bundle.putString("CourseIDString", courseIDString);

        addNewClass.putExtras(bundle);
        startActivity(addNewClass);
}

Edit 3: I also have a Landing (MAIN) activity which flashes for a second. On pressing back button from ClassActivityEdit activity Landing activity flashes again and then the ClassActivity activity loads. Finding it a bit tricky to solve.

public class LoadingPage extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loading_page);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent mainIntent = new Intent(LoadingPage.this, ClassActivity.class);
            startActivity(mainIntent);
        }
    }, 1000);
}

}

The problem is with your override to the back press (which does not need to be overridden) and is likely a symptom of with what your activity does when focus returns to it.

Firstly if you don't override onBackPress the previous activity will load (that's the default behaviour because of the backstack ) so you don't need to manually call it with a new intent and tell manually tell it to go to the previous activity.

When your parent activity (ClassActivity) then starts again it will go through the normal lifecycle - it will get resumed and all saved instance states get restored. Since you haven't posted it you need to make sure onResume and onRestart are not doing anything in your parent activity such as loading or setting data.

If you do keep the onBackPress you wrote then it will create a new instance and onCreate will always be called, unless it is singleInstance flagged, in which case onNewIntent will be called, but neither of these things seem to be what you want.

In response to your Edit 3 you need to make sure that LoadingPage has android:noHistory="true" so that it is not available to the backstack and then finish it explicitly to clean it up when you start the main class

That is a simple as calling finish when starting your intent

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        Intent mainIntent = new Intent(LoadingPage.this, ClassActivity.class);
        startActivity(mainIntent);
        finish(); //end the wrapping activity (LoadingPage)
    }
}, 1000);

The last thing you should be aware of is the difference between up and back navigation. In case you are navigating back via the home/up button you should also tell the manifest that these two activities are related. In the manifest entry for ClassActivityEdit you should add android:parentActivityName="com.teamtreehouse.oslist.ClassActivity"

Just let the back button do what it normally does. Don't override it and don't start a new activity. The parent activity is below the child activity in the stack, so it should appear when the child activity finishes.

By default, Android will retain activities in a stack, so when you go from Activity A to Activity B, Activity A will be brought back when you finish Activity B unless you do some other stuff like mess with the launchMode , finish A on returning from B, etc.

From what can be seen in your code, your problem should be solved by not overriding onBackPressed() in your child activity. Also, you should remove your <intent-filter> block for the child activity in the manifest.

I recommend reading up on managing the activity lifecycle and tasks and back stack .

First of all there is no need of overriding onBackPressed(). As Doug mentioned the parent activity is below the child activity in the stack , so it would be visible just after the child activity finishes on back pressed.

There is a suggestion for you as the ActionBarActivity is deprecated so it would be better to extend the class AppCompatActivity in your activity class.

I have tried to replicate the issue but failed. So I have created a classes.

LandingPage.java

public class LandingPage extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loading_page);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            startActivity(new Intent(LandingPage.this, ClassActivity.class));
        }
    }, 1000);
}

}

ClassActivity.java

public class ClassActivity extends AppCompatActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.class_activity);

    //Do whatever you want to  do

}
public void editListener(View v)
{
    Intent addNewClass = new Intent(ClassActivity.this,ClassActivityEdit.class);
    RelativeLayout buttonTableRow = (RelativeLayout) v.getParent();
    EditText getCourseID = (EditText) buttonTableRow.findViewById(R.id.courseNumberActivity);
    String courseIDString = getCourseID.getText().toString();
    addNewClass.putExtra("CourseIDString", courseIDString);
    startActivity(addNewClass);
}
}

ChildActivityEdit.java

public class ClassActivityEdit extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.class_activity_edit);
    String course_no = getIntent().getStringExtra("CourseIDString");
    Toast.makeText(ClassActivityEdit.this,course_no,Toast.LENGTH_SHORT).show();
    //Do whatever you want to  do

}
}

Your Problem is so much strange ! just by not overriding OnBackPressed you will get the result you want. I guess the problem is in your manifest.

android:noHistory="true"

It doesn't let the activity to stay in history stack, try removing it. also try this:

android:launchMode="singleInstance"

By doing this, the activity wont become created again.

Your main problem is that you have overridden onBackPressed in the child activity. What I understand from your code is- ClassActivity --> Parent Activity ClassActivityEdit --> Child Activity

In manifest, android:noHistory="true" is specified for child ie ClassActivityEdit activity. So it won't be stored in stack. Nothing is mentioned for parent.

In onBackPressed of your child activity you are again creating new Parent activity even though it is already present in the stack. It's just below your child activity.

Even if you don't override onBackPressed, parent activity will still load. In your case, it is creating many instances of parent activity.

One more thing, unless you want your activity to handle or respond to specific actions, you don't need to add intent filters for activity in manifest. According to documentation,

"Intent filter Specifies the types of intents that an activity, service, or broadcast receiver can respond to. An intent filter declares the capabilities of its parent component — what an activity or service can do and what types of broadcasts a receiver can handle. It opens the component to receiving intents of the advertised type, while filtering out those that are not meaningful for the component."

you can using Intent easily move for back Activity. but your back activity refresh all date write in onresum() method then it esyly refresh data

In child activity I have this code in java file

@Override
public void onBackPressed()
  {

   Intent moveback =
        new Intent(ClassActivityEdit.this, ClassActivity.class);
   startActivity(moveback);
   finish();
  }

When you start child activity from parent activity your parent activity move to stack and child activity display in onBackPressed event on child activity you create a new instance of parent activity and in activity life cycle onCreate event called first and views inside it creating by default values, so when you click on back button in child activity without creating a new instance of parent activity android display parent activity with previous savedInstanceState then onResume event called.

for more details see Activity Life Cycle

Change your onBackPressed() in child activity to this or you can also remove the onBackPressed() from child activity

@Override
public void onBackPressed(){
    super.onBackPressed();   // call super back pressed method  
}

Make sure that you don't finish() parent activity when you move from parent activity to child activity

Try using FLAG_ACTIVITY_REORDER_TO_FRONT when starting the ClassActivity intent.

you said,

On pressing back button from ClassActivityEdit activity Landing activity flashes again and then the ClassActivity activity loads.

you might be calling finish() somewhere in the ClassActivity which will cause the activity to be removed from the stack. If so, remove it.

@Override
public void onBackPressed(){
  finish();
  super.onBackPressed();
}

this will solve your issue. finish() will destroy your child activity and super.onBackPressed() will redirect you to parent activity.

You need to replace

startActivity(addNewClass);

with

startActivityForResult(addNewClass,101);

and then, in OnActivityResult you can refresh your data.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode==101){
       if(resultCode==RESULT_CANCELED){
           //refresh data accordingly
       }else if(resultCode==RESULT_OK){
           //refresh data accordingly
       }
    }
}

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