Global management of Activity

Global management of Activity
The app exit function is often used, which is generally implemented as follows:

  1. System.exit(0) uses the system's method to force the exit to be too violent
  2. Throw exception, forced exit experience is worse
  3. Broadcast exit performance waste
  4. Common methods for Application exit
    Advantage: when the Application starts, it will automatically create an Application for us, and only one Application can exist in an Application. Its life cycle is also synchronized with the Application, so you can manage the activity globally here: create a list to maintain the activity, add the activity when you create it, and remove the activity when you exit the activity. Look at the code:
public abstract class AbsSuperApplication extends Application {
    protected static Context context;
    protected static String appName;

    /**
     * Maintain Activity list
     */
    private static List<Activity> mActivitys = Collections
            .synchronizedList(new LinkedList<Activity>());

    @Override
    public void onCreate() {
        super.onCreate();
        context = this.getApplicationContext();
        appName =  getAppNameFromSub();
        registerActivityListener();
    }

    public static String getAppName() {
        return appName;
    }

    public static Context getContext() {
        return context;
    }

    protected abstract String  getAppNameFromSub();


    /**
     * @param activity Function Description: add an activity to the management
     */
    public void pushActivity(Activity activity) {
        mActivitys.add(activity);
        Loger.d("activityList:size:"+mActivitys.size());
    }

    /**
     * @param activity Function Description: delete an activity in the management
     */
    public void popActivity(Activity activity) {
        mActivitys.remove(activity);
        Loger.d("activityList:size:"+mActivitys.size());
    }



    /**
     * get current Activity Get the current Activity (last pushed in the stack)
     */
    public static Activity currentActivity() {
        if (mActivitys == null||mActivitys.isEmpty()) {
            return null;
        }
        Activity activity = mActivitys.get(mActivitys.size()-1);
        return activity;
    }

    /**
     * End current Activity (last pushed in stack)
     */
    public static void finishCurrentActivity() {
        if (mActivitys == null||mActivitys.isEmpty()) {
            return;
        }
        Activity activity = mActivitys.get(mActivitys.size()-1);
        finishActivity(activity);
    }

    /**
     * End the specified Activity
     */
    public static void finishActivity(Activity activity) {
        if (mActivitys == null||mActivitys.isEmpty()) {
            return;
        }
        if (activity != null) {
            mActivitys.remove(activity);
            activity.finish();
            activity = null;
        }
    }

    /**
     * End Activity for specified class name
     */
    public static void finishActivity(Class<?> cls) {
        if (mActivitys == null||mActivitys.isEmpty()) {
            return;
        }
        for (Activity activity : mActivitys) {
            if (activity.getClass().equals(cls)) {
                finishActivity(activity);
            }
        }
    }

    /**
     * Find activity by the specified class name
     *
     * @param cls
     * @return
     */
    public static Activity findActivity(Class<?> cls) {
        Activity targetActivity = null;
        if (mActivitys != null) {
            for (Activity activity : mActivitys) {
                if (activity.getClass().equals(cls)) {
                    targetActivity = activity;
                    break;
                }
            }
        }
        return targetActivity;
    }

    /**
     * @return Description: get the current top activity instance
     */
    public Activity getTopActivity() {
        Activity mBaseActivity = null;
        synchronized (mActivitys) {
            final int size = mActivitys.size() - 1;
            if (size < 0) {
                return null;
            }
            mBaseActivity = mActivitys.get(size);
        }
        return mBaseActivity;

    }

    /**
     * @return Description: get the name of the current top activity
     */
    public String getTopActivityName() {
        Activity mBaseActivity = null;
        synchronized (mActivitys) {
            final int size = mActivitys.size() - 1;
            if (size < 0) {
                return null;
            }
            mBaseActivity = mActivitys.get(size);
        }
        return mBaseActivity.getClass().getName();
    }

    /**
     * End all activities
     */
    public static void finishAllActivity() {
        if (mActivitys == null) {
            return;
        }
        for (Activity activity : mActivitys) {
            activity.finish();
        }
        mActivitys.clear();
    }

    /**
     * exit from application program
     */
    public  static void appExit() {
        try {
            Loger.e("app exit");
            finishAllActivity();
        } catch (Exception e) {
        }
    }


    private void registerActivityListener() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    /**
                     *  Listen to the Activity creation event and add the Activity to the list
                     */
                    pushActivity(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) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {
                    if (null==mActivitys&&mActivitys.isEmpty()){
                        return;
                    }
                    if (mActivitys.contains(activity)){
                        /**
                         *  Listen to the Activity destroy event to remove the Activity from the list
                         */
                        popActivity(activity);
                    }
                }
            });
        }
    }
}

Partial explanation:

1.private static List mActivitys = Collections
.synchronizedList(new LinkedList());`

Using Collections.synchronizedList ensures thread safety
2.registerActivityLifecycleCallbacks is the callback method listened by the life cycle of activity.
3.
Exit the application, loop through finish, close all activities, clear the collection, and use try/catch to prevent the exit method from being abnormal.

/**
     * exit from application program
     */
    public  static void appExit() {
        try {
            Loger.e("app exit");
            finishAllActivity();
        } catch (Exception e) {
        }
    }
 /**
     * End all activities
     */
    public static void finishAllActivity() {
        if (mActivitys == null) {
            return;
        }
        for (Activity activity : mActivitys) {
            activity.finish();
        }
        mActivitys.clear();
    }

Use: create its subclass to inherit the AbsSuperApplication and implement its abstract methods

 @Override
    protected String getAppNameFromSub() {
        PackageManager pm = this.getPackageManager();
        String appName = getApplicationInfo().loadLabel(pm).toString();
        return appName;
    }

The benefits of global management can help us to end the application or create a global Dialog. More convenient

Added by noeledoran on Wed, 01 Apr 2020 19:05:17 +0300