简体   繁体   中英

How to know when you returned to an activity because of the back button?

My MainActivity leads to SecondActivity. If the user presses the phone's back button the app goes back to the MainActivity.

How can I execute something when this happens?

(I know I could put code in SecondActivity to add functionality to the back button so it passes a result to MainActivity, but I don't want to do that to every possible screen that could lead back to the MainActivity.)

Perhaps another way of asking, how can I know that MainActivity is showing because of pressing the back button rather than having been formally requested with an intent?

Background

I think here is the logic to implement this requirement:

  1. When users press the back key on the current activity, we will remember that action.

  2. When users go back to the previous activity, we will check whether there is a back key pressed action exits or not.

Implementation

Step 1. Create a base activity class named BaseActivity . Every activity in your app should extend from this class.

class BaseActivity extends AppCompatActivity {

    public static String IS_BACK_KEY_PRESSED = "IS_BACK_KEY_PRESSED";

    @Override
    public void onBackPressed() {
        // Remember the user's press of the back key action
        getIntent().putExtra(IS_BACK_KEY_PRESSED, true);

        // Call the super's method
        super.onBackPressed();
    }

    /**
     * Called when the activity has been resumed from an activity
     * that has been destroyed because of user's press of the back key
     */
    public void onGoBackFromAnotherActivity() {
    }
}

Step 2. Create a class named MyApp that extends from the Application class. Its purpose is to listen to all activity lifecycle of the app by using registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks)

public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacksImpl());
    }

    private static final class ActivityLifecycleCallbacksImpl implements ActivityLifecycleCallbacks {
        boolean isBackKeyPressed = false;

        @Override
        public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
        }

        @Override
        public void onActivityStarted(@NonNull Activity activity) {
            if (activity instanceof BaseActivity) {
                if (isBackKeyPressed) {
                    ((BaseActivity) activity).onGoBackFromAnotherActivity();
                    isBackKeyPressed = false;
                }
            }
        }

        @Override
        public void onActivityResumed(@NonNull Activity activity) {
        }

        @Override
        public void onActivityPaused(@NonNull Activity activity) {
            if (activity instanceof BaseActivity) {
                Bundle data = activity.getIntent().getExtras();
                if (data != null) {
                    isBackKeyPressed = data.getBoolean(BaseActivity.IS_BACK_KEY_PRESSED);
                } else {
                    isBackKeyPressed = false;
                }
            }
        }

        @Override
        public void onActivityStopped(@NonNull Activity activity) {
        }

        @Override
        public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
        }

        @Override
        public void onActivityDestroyed(@NonNull Activity activity) {
        }
    }
}

Remember to add this class to AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.kotlinapp">

    <application
        android:name=".MyApp"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity" />

    </application>

</manifest>

Usage

MainActivity.java

public class MainActivity extends BaseActivity {

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

    @Override
    public void onGoBackFromAnotherActivity() {
        // Your code logic goes here.
    }
}

SecondActivity.java

public class SecondActivity extends BaseActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }
}

Edit: Check if any activity (without knowing which) returned to desired activity

To check in Activity A, use:

@Override
protected void onResume() {
    super.onResume();
    // TODO: Work
}

As stated in the comment, onResume will be called on an activity/fragment when:

  1. Activity runs for the first time
  2. Activity comes back into focus (from another activity, launcher, recent, another app)

However, you cannot track what triggered it, or what happened before it.


---------- Outdated ----------


Between Activity A and Activity B

use

startActivityForResult(intent, CHOOSE_AN_INT_VALUE_TO_INDICATE_IT_REQUESTS_FOR_BACK_PRESS);

In Activity A, and in Activity B, use

    @Override
    public void onBackPressed() {
        setResult(CHOOSE_AN_INT_VALUE_TO_INDICATE_IT_CAME_FROM_BACK_PRESS);
        finish();
    }

Then again in Activity A, use

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CHOOSE_AN_INT_VALUE_TO_INDICATE_IT_REQUESTS_FOR_BACK_PRESS && resultCode==CHOOSE_AN_INT_VALUE_TO_INDICATE_IT_CAME_FROM_BACK_PRESS) {
        // TODO: Do your work
    }
}

If these 3 portions are implemented, you don't need to check for which activity triggered back press, you can simply compare the request and result codes

I hope this helps!!

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