Android 对进程和内存的管理
如果内存足够,Android不会杀掉任何进程,如果内存不足就是进程随时可能会被杀掉。
而Android会在内存充足的时候,恢复被杀掉的进程。
也就是说静态变量的值,如果不做处理,是不可靠的,可以说内存中的一切都不可靠。
如果要可靠,还是得保存到文件中去,在恢复应用的时候恢复回来。
Android Application其实是一个单例对象,也是放在内存中的,当进程被杀掉,缓存数据就全清空了,只不过Android系统会帮恢复Application,恢复之后又会恢复上次打开的Activity的页面,然后停在上次打开的Activity的页面,而我们存放在Application的缓存数据(包含静态变量数据)自然就没有了,还是得自己处理。
不过我们可以在Application被销毁时直接退出程序,其实Application都被销毁了,程序就应该退出的。
看完之后是不是感觉都要晕了,Android 你杀死进程就杀死嘛,干嘛又要恢复。。。恢复之后,再用一些缓存数据(Application里的数据,静态变量数据等等),就容易造成一些问题(比如:NullPointerException),为了避免这些问题,我们要在内存不足的时候彻底杀死App。
以下代码在项目里,项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2
1.写一个Activity的管理类。
package com.phone.common_library.manager;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.text.TextUtils;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* author : Urasaki
* e-mail : 1164688204@qq.com
* date : 2020/3/10 14:05
* introduce :
*/
public class ActivityPageManager {
private static final String TAG = "ActivityPageManager";
/**
* 单一实例
*/
private static ActivityPageManager mActivityPageManager;
/**
* Activity栈 Stack:线程安全
*/
private Stack<Activity> mActivityStack = new Stack<>();
/**
* 還存活的Activity栈
*/
private Stack<Activity> mActivityAliveStack = new Stack<>();
/**
* 是否是棧中最後一個存活的Activity
*/
private AtomicBoolean isLastAliveActivity = new AtomicBoolean(false);
/**
* 私有构造器 无法外部创建
*/
private ActivityPageManager() {
}
/**
* 获取单一实例 双重锁定
*
* @return this
*/
public static ActivityPageManager getInstance() {
if (mActivityPageManager == null) {
synchronized (ActivityPageManager.class) {
if (mActivityPageManager == null) {
mActivityPageManager = new ActivityPageManager();
}
}
}
return mActivityPageManager;
}
/**
* 添加Activity到栈
*/
public void addActivity(Activity activity) {
mActivityStack.add(activity);
}
/**
* 移除栈中的Activity
*
* @param activity Activity
*/
public void removeActivity(Activity activity) {
if (activity != null && mActivityStack.contains(activity)) {
mActivityStack.remove(activity);
}
}
/**
* 获取当前Activity (堆栈中最后一个添加的)
*
* @return Activity
*/
public Activity getCurrentActivity() {
return mActivityStack.lastElement();
}
/**
* 获取指定类名的Activity
*/
public Activity getActivity(Class<?> cls) {
if (mActivityStack != null)
for (Activity activity : mActivityStack) {
if (activity.getClass().equals(cls)) {
return activity;
}
}
return null;
}
/**
* 结束当前Activity (堆栈中最后一个添加的)
*/
public void finishCurrentActivity() {
Activity activity = mActivityStack.lastElement();
finishActivity(activity);
}
/**
* 结束指定的Activity
*
* @param activity Activity
*/
public void finishActivity(Activity activity) {
if (activity != null && mActivityStack.contains(activity)) {
mActivityStack.remove(activity);
LogManager.i(TAG, "finishActivity");
activity.finish();
}
}
/**
* 结束指定的Activity
*
* @param activity Activity
*/
public void finishAliveActivity(Activity activity) {
if (activity != null && mActivityAliveStack.contains(activity)) {
mActivityAliveStack.remove(activity);
LogManager.i(TAG, "finishActivity");
activity.finish();
}
}
/**
* 结束指定类名的Activity
*
* @param clazz Activity.class
*/
public void finishActivity(Class<?> clazz) {
for (Activity activity : mActivityStack) {
if (activity.getClass().equals(clazz)) {
finishActivity(activity);
break;
}
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity() {
mActivityAliveStack.clear();
for (int i = mActivityStack.size() - 1; i >= 0; i--) {
if (mActivityStack.get(i) != null) {
mActivityAliveStack.add(mActivityStack.get(i));
}
}
for (int i = mActivityAliveStack.size() - 1; i >= 0; i--) {
if (i == 0) {
isLastAliveActivity.set(true);
LogManager.i(TAG, "isLastAliveActivity.set(true)");
}
finishAliveActivity(mActivityAliveStack.get(i));
}
mActivityAliveStack.clear();
mActivityStack.clear();
}
public AtomicBoolean isLastAliveActivity() {
return isLastAliveActivity;
}
/**
* 结束某个Activity之外的所有Activity
*/
public void finishAllActivityExcept(Class<?> clazz) {
for (int i = mActivityStack.size() - 1; i >= 0; i--) {
if (mActivityStack.get(i) != null && !mActivityStack.get(i).getClass().equals(clazz)) {
finishActivity(mActivityStack.get(i));
}
}
}
/**
* 退出应用程序
*/
public void exitApp() {
try {
finishAllActivity();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.exit(0);
}
}
/**
* 退出应用程序(最後一個存活的Activity退出的时候(onDestroy)做了退出應用程序處理)
*/
public void exitApp2() {
try {
LogManager.i(TAG, "exitApp2");
finishAllActivity();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 判断某个Activity 界面是否在前台
*
* @param context
* @param className 某个界面名称
* @return
*/
public static boolean isForeground(Context context, String className) {
if (context == null || TextUtils.isEmpty(className)) {
return false;
}
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
if (list != null && list.size() > 0) {
ComponentName cpn = list.get(0).topActivity;
if (className.equals(cpn.getClassName())) {
return true;
}
}
return false;
}
}
2.写一个BaseActivity,然后在BaseActivity添加以下方法,让所有的Activity继承这个BaseActivity。
private void killAppProcess(Context context) {
LogManager.i(TAG, "killAppProcess");
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> processInfos = manager.getRunningAppProcesses();
// 先杀掉相关进程,最后再杀掉主进程
for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : processInfos) {
if (runningAppProcessInfo.pid != android.os.Process.myPid()) {
android.os.Process.killProcess(runningAppProcessInfo.pid);
}
}
android.os.Process.killProcess(android.os.Process.myPid());
// 正常退出程序,也就是结束当前正在运行的 java 虚拟机
System.exit(0);
}
@Override
protected void onDestroy() {
if (activityPageManager != null) {
if (activityPageManager.isLastAliveActivity().get()) {
killAppProcess(baseApplication);
}
activityPageManager.removeActivity(rxAppCompatActivity);
}
super.onDestroy();
}
3.写一个BaseApplication,然后在BaseApplication添加以下方法,让自己的Application继承BaseApplication。
package com.phone.common_library;
public class BaseApplication extends Application {
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level == TRIM_MEMORY_MODERATE) {
//App开始自杀,清理掉所有的activity(最後一個存活的Activity退出的时候(onDestroy)做了退出應用程序處理)
activityPageManager.exitApp2();
}
}
}
因内存不足进程被杀掉,而Android会在内存充足的时候,恢复被杀掉的进程,然后再用一些缓存数据(Application里的数据,静态变量数据等等),就容易造成一些问题(比如:NullPointerException)。
这样就可以在内存不足的时候彻底杀死App,避免因以上原因造成的问题了。
如对此有疑问,请联系qq1164688204。
推荐Android开源项目
项目功能介绍:RxJava2 和Retrofit2 项目,使用Kotlin+RxJava2+Retrofit2+MVP架构+组件化/Kotlin+Retrofit2+协程+MVVM架构+组件化,添加自动管理token 功能,添加RxJava2 生命周期管理,集成极光推送、阿里云Oss对象存储和高德地图定位功能。
项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2