Detailed Explanation of Android ActivityManager Use Case

  • 2021-12-19 06:36:41
  • OfStack

Preface

Activity can obtain application information in operation, and can obtain servcie, process, app, memory, Task information and so on.

Getting information

ActivityManager.MemoryInfo
Important Fields in MemoryInfo: availMem (System Available Memory), totalMem (Total Memory), threshold (Low Memory Threshold), lowMemory (Low Memory State) Debug.MemoryInfo
Debug. MemoryInfo is mainly used to obtain memory information under the process. ActivityManager.RunningAppProcessInfo
Encapsulates the information of the running process, related fields: processName (process name), pid (process pid), uid (process uid), pkgList (all packages under the process). ActivityManager.RunningServiceInfo
It is used to encapsulate the running service information, but there are 1 other information besides the service process information, activeSince (when and how the service was activated for the first time) and foreground (whether the service is executed in the background). ActivityManager.RunningTaskInfo
Used to encapsulate Task information, including id (the only one identification of the task), baseActivity (the foundation of the task stack Activity), topActivity (Activity at the top of the task stack), numActivities (the number of Activity in the task stack), description (the current state description of the task), etc.

Common Methods of ActivityManager

clearApplicationUserData (): Used to erase user data, which is equivalent to erasing user data in mobile phone settings. addAppTask (Activity activity, Intent intent, ActivityManager. TaskDescription description, Bitmap thumbnail): Create a new task stack for Activity, activity (Activity for creating a task stack), intent (Intent for jumping pages), description (description information), thumbnail (thumbnail) getDeviceConfigurationInfo (): Get device information getLauncherLargeIconSize (): Gets the size of the Launcher (launcher) icon getMemoryInfo (ActivityManager. MemoryInfo outInfo): Get the current memory information of the system getProcessMemoryInfo (): Returns memory usage by one or more processes getRunningAppProcesses (): Gets the list of application processes on the device getAppTasks (): Get the current application task list isUserAMonkey (): Whether the user is a monkey, used to judge whether the keyboard is pressed indiscriminately killBackgroundProcesses (String packageName): Kill the corresponding process according to the package name getRunningTasks (int maxNum): Get a list of running tasks getRecentTasks (int maxNum, int flags): Gets a list of user-initiated tasks getMyMemoryState (ActivityManager. RunningAppProcessInfo outState): Gets the global memory state of the process

Judge whether the application is running in the foreground and whether the application is running


// Determine whether the application is running in the foreground 
public boolean isRunningForeground(Context context){
        String packageName=getPackageName(context);
        String topActivityClassName=getTopActivityName(context);
        System.out.println("packageName="+packageName+",topActivityClassName="+topActivityClassName);
        if (packageName!=null&&topActivityClassName!=null&&topActivityClassName.startsWith(packageName)) {
            System.out.println(" The application is executed in the foreground ");
            return true;
        } else {
            System.out.println(" The application is executed in the background ");
            return false;
        }
    }

//  Determine if the application is running 
public boolean isRun(Context context,String mPackageName){
        ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> list = am.getRunningTasks(100);
        boolean isAppRunning = false;
        //100 Represents the maximum number of tasks taken, info.topActivity Represents the currently running Activity , info.baseActivity Indicates that this process is running in the background of the system 
        for (RunningTaskInfo info : list) {
            if (info.topActivity.getPackageName().equals(mPackageName) || info.baseActivity.getPackageName().equals(mPackageName)) {
                isAppRunning = true;
                Log.i("ActivityService",info.topActivity.getPackageName() + " info.baseActivity.getPackageName()="+info.baseActivity.getPackageName());
                break;
            }
        }
        if(isAppRunning){
            Log.i("ActivityService", " The program is running ");
        }else{
            Log.i("ActivityService", " The program is not running ");
        }
        return isAppRunning;
}

// Get the top of the stack ActivityName
public  String getTopActivityName(Context context){
        String topActivityClassName=null;
         ActivityManager activityManager =
        (ActivityManager)(context.getSystemService(android.content.Context.ACTIVITY_SERVICE )) ;
         List<runningtaskinfo> runningTaskInfos = activityManager.getRunningTasks(1) ;
         if(runningTaskInfos != null){
             ComponentName f=runningTaskInfos.get(0).topActivity;
             topActivityClassName=f.getClassName();
         }
         return topActivityClassName;
    }

    public String getPackageName(Context context){
         String packageName = context.getPackageName();  
         return packageName;
    }

Custom ActivityManager Management Activity

We need to define our own ActivityManager, and put the started Activity into the stack through our custom ActivityManager in the OnCreate method in BaseActivity, and unstack Activity in the onDestroy method.


/**
 * 用于管理Activity,获取Activity
 * 在结束1个activity后应该判断当前栈是否为空,为空则将本类引用置为null,以便于虚拟机回收内存
 * 单例,调用 {@link #getActivityManager()} 获取实例
 * 成员变量 {@link #mActivityStack} 应该与系统的回退栈保持1致,所以在启动activity的时候必须在其onCreate中
 * 将该activity加入栈顶,在activity结束时,必须在onDestroy中将该activity出栈
 */

public class ActivityManager {

    private static ReStack<Activity> mActivityStack;    //Activity栈
    private static ActivityManager mInstance;

    private ActivityManager() {
        mActivityStack = new ReStack<>();
    }

    /**
     * 获取ActivityManager的单例.
     *
     * @return ActivityManager实例
     */
    public static ActivityManager getActivityManager() {
        if (mInstance == null) {
            mInstance = new ActivityManager();
        }
        return mInstance;
    }

    /**
     * 添加1个activity到栈顶.
     *
     * @param activity 添加的activity
     */
    public void pushActivity(Activity activity) {
        if (mActivityStack == null) {
            mActivityStack = new ReStack<>();
        }
        mActivityStack.push(activity);
    }

    /**
     * 获取栈顶的Activity.
     *
     * @return 如果栈存在, 返回栈顶的activity
     */
    public Activity peekActivity() {
        if (mActivityStack != null && !mActivityStack.isEmpty()) {
            return mActivityStack.peek();
        } else {
            return null;
        }
    }

    /**
     * 结束当前的activity,在activity的onDestroy中调用.
     */
    public void popActivity() {
        if (mActivityStack != null && !mActivityStack.isEmpty()) {
            mActivityStack.pop();
        }
        //如果移除1个activity之后栈为空,将本类的引用取消,以便于让虚拟机回收
        if (mActivityStack != null && mActivityStack.isEmpty()) {
            mInstance = null;
        }
    }

    /**
     * 结束最接近栈顶的匹配类名的activity.
     * 遍历到的不1定是被结束的,遍历是从栈底开始查找,为了确定栈中有这个activity,并获得1个引用
     * 删除是从栈顶查找,结束查找到的第1个
     * 在activity外结束activity时调用
     *
     * @param klass 类名
     */
    public void popActivity(Class<? extends BaseActivity> klass) {
        for (Activity activity : mActivityStack) {
            if (activity != null && activity.getClass().equals(klass)) {
                activity.finish();
                break;              //只结束1个
            }
        }
    }

    //移除所有的Activity
    public void removeAll(){
        for (Activity activity : mActivityStack) {
            if (activity != null) {
                activity.finish();
                break;              
            }
        }
    }
}

Related articles: