Author: Carson_Ho

Address: http://www.jianshu.com/p/269873a16937

Disclaimer: This article is written by Carson_Ho and has been published with permission. Please do not reprint it without the permission of the original author

preface

  • In Android development, there is often a need to “exit an App with one click”

  • But there are too many “one-click exit App” implementations out there that don’t work

  • This article will comprehensively summarize the implementation of “one-click exit App”, and give you a practice, I hope you will enjoy.

directory

Nature of demand

There are actually two requirements for one-click exit from App:

  1. End all activities in the current App with one click

  2. End the current App process with one click

That is, it takes 2 steps to complete the one-click exit App requirement. Below, I’ll walk you through these two steps.

Function implementation

(Step 1) End all activities in the current App with one click

Implementation method type

  • There are two main categories: through Android components & self-implementation

  • The details are as follows:

Note: The above method only ends all activities in the current App (indeed exits the App from the user’s perspective), but the App process is not actually finished.

Detailed introduction

Through the Android component: Activity

Method 1: Use the Activity startup mode: SingleTask

  • The principle of

A. Entry Activity is now at the bottom of the stack

B. The principle of SingleTask is as follows:

All Activity instances above the entry Activity are automatically closed and removed & are placed at the top of the stack (this is a feature of SingleTask startup mode).

OnNewIntent () is called when a subsequent Activity starts an Activity at the bottom of the task stack.

  1. You do this by closing itself in onNewIntent() of the entry Activity callback

  2. Start the entry Activity when you need to exit the App

  3. Start the App entry Activity in SingleTask mode

  • The specific implementation

  • Step 1: Set the App entry Activity to “SingleTask” startup mode

    / / AndroidMainifest. The Activity of XML configuration set < activityandroid: launchMode attribute = “singleTask” / / / / standard: standard mode / / singleTop: //singleInstance: singleInstance // If this is not set, the Activity starts in standard mode by default. </ Activity >

    Step 2: Rewrite the Activity onNewIntent() in the entry

    @override protected void onNewIntent(Intent Intent) {super.onnewintent (Intent Intent); if (intent ! Intent.getbooleanextra (“exit”, false); If (isExitApp) {// Close itself this.finish(); }}}

    Step 3: Call exitApp() when you need to exit

    private void exitApp() { Intent intent = new Intent(context, MainActivity.class); intent.putExtra(“exit”, true); context.startActivity(intent); // end the process // system.exit (0); }

    • Advantages 1. Simple & convenient to use

    • disadvantages

    1. Specify that the entry Activity of App adopts SingleTask startup mode

    2. Limited scope: You can only end an Activity in the current task stack, and cannot process an Activity in a multi-task stack (i.e., using SingleInstance startup mode)

  • Application Scenario 1. Activity Single-task stack

  • Method 2:Use the Activity to start the flag bit

    • Principle: On the entranceActivityUsing 2 marker bits:

    1. Intent.flag_activity_clear_top: Destroys the target Activity and all activities above it and recreates the target Activity

    2. Intent.flag_activity_single_top: If the Activity is launched at the top of the task stack, the instance of the Activity is not rebuilt. Instead, the instance at the top of the stack is reused (call onNewIntent()).

  • Specific use (fromMainActivity(the entranceActivity) to jump toActivity2& One-click Exit)

  • Step 1: Set to override onNewIntent() in MainActivity

    // Set the button to jump to Activity2

    button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(MainActivity.this, Activity2.class)); }}); } // Pass an identifier to onNewIntent (). app@override protected void onNewIntent(Intent Intent) {super.onnewintent (Intent Intent); if (intent ! Intent.getbooleanextra (“exit”, false); If (isExitApp) {// Close itself this.finish(); }} // end the process // system.exit (0); }}

    Step 2: Start MainActivity where you want to exit (Activity2) & set the flag bit

    Intent Intent = new Intent(); intent.setClass(Activity2.this, MainActivity.class); Intent.setflags (intent.flag_activity_clear_top); Intent.addflags (intent.flag_activitY_singLE_TOP); intent.flag_activitY_singLE_top (intent.flag_activitY_singLE_TOP); // Step 2: If the Activity is started at the top of the task stack, the instance of the Activity is not rebuilt. Instead, the instance at the top of the stack is reused (calling onNewIntent() of the instance) // In Step 1: Activity2 on top of MainActivity is destroyed, and MainActivity is at the top of the stack. PutExtra (“exit”, true); putExtra(“exit”, true); putExtra(“exit”, true); startActivity(intent);

    • Advantages 1. Simple & convenient to use

    • Disadvantages 1. Limited scope: You can only end the Activity in the current task stack, and cannot process the Activity in the multi-task stack (that is, using SingleInstance startup mode)

    • Application Scenario 1. Activity Single-task stack

    Method 3: Through the system task stack

    • Principle: throughActivityManagerGet the current system task stack & put all in the stackActivityOne out of

    • The specific use

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) // 1. ActivityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); / / 2. Through the ActivityManager for task List < ActivityManager, AppTask > appTaskList = ActivityManager. GetAppTasks (); / / 3. Shutting down the Activity for (ActivityManager, AppTask AppTask: appTaskList) {AppTask. FinishAndRemoveTask (); } // 4. End the process // system.exit (0);

    • Advantages 1. Simple and convenient to use

    • disadvantages

    1. Limited scope: You can only end an Activity in the current task stack, and cannot process an Activity in a multi-task stack (i.e., using SingleInstance startup mode)

    2. High requirements for Android version: Android 5.0 or higher

    • Application Scenario 1. Activity single-task stack for Android 5.0 or higher

    Android components: BroadcastReceiver

    BroadcastReceiver is used to broadcast listening

    • Principle: In everyActivityRegister broadcast receiver in (response action = close itself); When it’s time to quitAppSend a broadcast request when

    • The specific implementation

    Step 1: Customize broadcast receivers

    public class ExitAppReceiver extends BroadcastReceiver {    private Activity activity;    public ExitAppReceiver(Activity activity){        this.activity = activity;    }    @Override    public void onReceive(Context context, Intent intent) {        activity.finish();    }}

    Step 2: Register broadcast receivers in each Activity (response action = close itself)

    Public class Activity extends AppCompatActivity {private ExitAppReceiver mExitAppReceiver; Protected void onCreate(Bundle savedInstanceState) {super.oncreate (savedInstanceState); setContentView(R.layout.activity_main); mExitAppReceiver = new ExitAppReceiver(this); registerReceiver(mExitAppReceiver,new IntentFilter(BaseApplication.EXIT)); }// 1. Protect void onDestroy() {super.ondestroy (); unregisterReceiver(mExitAppReceive); }

    Step 3: Send a broadcast request when you need to exit the App

    context.sendBroadcast(new Intent(BaseApplication.EXIT));

    // Note: this cannot be used: system.exit (0); // Cause: After sending the broadcast method, the program will not wait for the broadcast receiver to receive the next sentence system.exit (0), which is immediately changed to system.exit (0).

    • advantages

      1. Wide application scenarios: considering single/multi-task stack & multi-boot mode

    • Disadvantages 1. Complex implementation: you need to register broadcast receivers in each Activity

    • Application Scenario 1. Exit the App with one key in any case, but the App process cannot be terminated

    So it’s just a one-click exit from the App from the user’s perspective.

    Its implementation

    Method 1: Create a linked list
    • Principle: through inApplicationCreate one in a subclassActivityLinked list: Saves running listsActivityInstance; When a one-click exit is requiredAppWhen putting all the linked lists insideActivityExit each instance one by one

    • The specific use

    Step 1: Create a linked list of activities in a BaseApplication subclass

    public class Carson_BaseApplicaiton extends Application {

    Public static LinkedList<Activity> activityLinkedList; @Override public void onCreate() { super.onCreate(); activityLinkedList = new LinkedList<>(); registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log.d(TAG, “onActivityCreated: ” + activity.getLocalClassName()); activityLinkedList.add(activity); } @override public void onActivityDestroyed(Activity Activity) {log.d (TAG, “onActivityDestroyed: ” + activity.getLocalClassName()); activityLinkedList.remove(activity); Public void onActivityStarted(Activity Activity) {} @override public void onActivityStarted(Activity Activity) {} @override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } }); } public void exitApp() {log.d (TAG, “Activity list in container “); / / print the current container Activity list for (Activity Activity: activityLinkedList) {the d (the TAG, the Activity getLocalClassName ()); } log. d(TAG, “phasing out all activities in the container “); // Exit Activity for (Activity Activity: activityLinkedList) {activity.Finish (); } // End the process // system.exit (0); }// Remember to add <application Android :name=”.carson_baseApplicaiton “…. to manifest.xml </application>

    Step 2: get the Applicaiton class object & call exitApp() when you need to exitApp with one click

    private Carson_BaseApplicaiton app;

    app = (Carson_BaseApplicaiton)getApplication(); app.exitApp();

    • rendering

    • advantages

      1. Wide application scenarios: considering single/multi-task stack & multi-boot mode

    • disadvantages

      1. The Activity needs to go through the normal life cycle, which calls onCreate () when it is created and onDestroy () when it ends.

    This is the only way to properly write and write an Activity to the container through a normal life cycle

    • Application scenarios

      1. Exit App implementation with one key in any case

    Method 2: RxBus

    • Principle: UseRxBusAct as an event bus in eachActivityRegistered in theRxBusSubscribe (response action = close itself); Send the exit event request when you need to exit the App.

    • The specific use

    Step 1: Register the RxBus subscription in each Activity (response action = close itself)

    public class Activity extends AppCompatActivity {

    private Disposable disposable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity2); Subscribe (new Consumer<String>() {@override); // Register the RxBus subscription disposable = rxbus.getInstance ().toobServable (string.class).subscribe(new Consumer<String>() {@override Public void Accept (String s) throws Exception {// Response action = close yourself if (s.quals (“exit”)){finish(); }}}); Override protected void onDestroy() {if (! disposable.isDisposed()){ disposable.dispose();; }}

    Step 2: Send an exit event when you need to exit the App

    RxBus.getInstance().post(“exit”);

    System.exit(0);

    • Advantages 1. Can be combined with RxJava & RxBus

    • Disadvantages 1. Complexity of implementation: RxBus itself is difficult to implement & requires registering and unsubscribing to RxBus for every Activity

    • Application Scenario 1. When used with RxJava

    If the project does not use RxJava & RxBus, do not use it

    • At this point, the method of ending all activities in the current App is explained.

    • Note: The above method only ends all activities in the current App (indeed exits the App from the user’s perspective), but the App process is not actually finished

    (Step 2) End the current App process

    The local method of Dalvik VM is mainly used

    • Ends the current Activity & ends the process

    That is, after (Step 1) ending all activities in the current App, call this method to exit the App with one click (more on the end process).

    • The specific use

    / / way 1: android. OS. Process. KillProcess ()

    Android. OS. Process. KillProcess (android. OS. Process. MyPid ()); Exit (0) = Exit (0); exit(0) = exit(0); // system.exit (0) : exit normally; // system.exit (0) : exit normally; // 2.system.exit (1) : An abnormal exit. Normally this exit should be placed in a catch block.

    • Pay special attention to the hypothetical scenario: what happens when you call the above two methods if the current Activity does not equal the last Activity in the current task stack? (that is, activity1-Activity2-activity3 (calling the above two methods on Activity3))

    A:

    1. End Activity3 (current Activity) & End the process

    2. Restart the process again & start Activity1, Activity2

    That is, in Android, calling the above Dalvik VM local method results in:

    1. End the current Activity & End the process

    2. Then restart the process & the Activity that was started before it was started in addition to the current Activity

    • The reason:

      1. ActivityManager on Android is always listening for processes **. It will try to restart the process if it detects that it has terminated abnormally.

    • Application Scenario 1. When only the current Activity is left in the task stack (that is, after exiting other activities), call this method to exit the process. That is, after (Step 1) ending all activities in the current App, call this method to exit the App with one key.

    Note: This differs from “Finish () on the last Activity call” : Finish () does not end the process, as the above two methods do

    Now, the two-step explanation of one-click exit App is complete.

    The Demo address

    About the above said method Demo at https://github.com/Carson-Ho/App_1shot_Finsh

    conclusion

    • To realize the one-click exit function of the App, you actually need to complete two steps: Step 1: One-click end of all activities in the current App Step 2: One-click end of the current App process

    • The methods for each step are summarized below

    • I’m going to continue to talk about Android in more depth. If you’re interested, please stay tuned for Carson_Ho’s Android development notes

    welfare

    Welcome to participate in the “Android Dry Goods shop” after-holiday book benefits

    “Android Dry Goods Shop” after the holiday book bonus – thank you all for your support!

    Recommended reading

    1, Android frosted glass blur effect, I use OpenCV to do

    Android DataBinding & MVVM

    3. I don’t write a line of code to implement the Toolbar! And you’re still wrapping BaseActivity?