需求 进入系统后,用户进入一些经常使用的应用,可以快速打开,类似于之前已经打开过,然后,可以快速进入应用界面。
实现 1.前端机器,上报应用的使用频率&使用时间到后台 2.后台利用前端的上报,采用一定的策略(比如用户经常使用的应用& 根据用户的使用频率,预测用户将要使用的应用等),下发需要快速启动的应用列表 3.前端接收到快速启动应用列表,在系统启动阶段,直接准备好应用程序的进程,但是不直接拉起应用程序的Activity(注意,只是准备好进程),从而达到后续启动应用程序时,不需要准备进程启动的阶段,直接启动Activity。 4.AMS中维护一个列表,低内存回收针对这个快速启动列表的,直接忽略
Coding
private void startProcess(List<PackageInfoItem> packageList) {
if (packageList == null || packageList.size() == 0) {
return;
}
for(PackageInfoItem packageInfo : packageList) {
IActivityManager manager = ActivityManagerNative.getDefault();
try {
Log.i(TAG, "startProcess packageName = " + packageInfo);
Class<?> aClass = Class.forName("android.app.IActivityManager");
Method method = aClass.getMethod("startApplication", String.class);
method.invoke(manager, packageInfo.getPackageName());
} catch(Exception e) {
e.printStackTrace();
}
}
}
底层增加startApplication 方法,实际最终上调用的是:AMS->startProcessLocked
core/java/android/app/ActivityManagerNative.java | 19 +++++++
core/java/android/app/IActivityManager.java | 6 +++
.../android/server/am/ActivityManagerService.java | 60 +++++++++++++++++++---
3 files changed, 78 insertions(+), 7 deletions(-)
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 29b47fe..77eb329 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2608,6 +2608,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
+ case START_APPLICATION_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ final String packageName = data.readString();
+ startApplication(packageName);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -6085,5 +6092,17 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
+ @Override
+ public void startApplication(String packageName) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(packageName);
+ mRemote.transact(START_APPLICATION_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 40d99b4..a4c2d90 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -530,6 +530,11 @@ public interface IActivityManager extends IInterface {
public void killNativeProcess(int[] pids) throws RemoteException;
+
+
+ public void startApplication(String packageName) throws RemoteException;
+
+
@@ -884,4 +889,5 @@ public interface IActivityManager extends IInterface {
int KILL_NATIVE_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 306;
int SET_IS_PLAYING_VIDEO = IBinder.FIRST_CALL_TRANSACTION + 307;
int SET_SYSTEM_PROPERTY = IBinder.FIRST_CALL_TRANSACTION + 308;
+ int START_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 309;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c8808a0..9d91a16 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1451,6 +1451,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
+ private List<String> mAutoStartAppList = new ArrayList<String>();
+
@Override
public void killNativeProcess(int[] pids) {
@@ -19793,8 +19795,13 @@ public final class ActivityManagerService extends ActivityManagerNative
Boolean needKillService = false;
int adj_min = 0;
- if (ams_killprocess_stage1 == 0)
+ if (isAutoStartApp(app)) {
+ return true;
+ }
+
+ if (ams_killprocess_stage1 == 0) {
return false;
+ }
if (Looper.getMainLooper() != Looper.myLooper()) {
return false;
@@ -19875,6 +19882,11 @@ public final class ActivityManagerService extends ActivityManagerNative
" app.curAdj = " + app.curAdj + " app.curProcState = " + app.curProcState +
" app.cached = " + app.cached + " app.empty = " + app.empty + " app.adj_type = " + app.adjType);
+
+ if (isAutoStartApp(app)) {
+ return;
+ }
+
if (!app.killedByAm && app.thread != null) {
if (((app.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) &&
@@ -21648,12 +21660,46 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
- private boolean isCorrectIp(String ip) {
- if(TextUtils.isEmpty(ip)) {
- return false;
+
+
+ @Override
+ public void startApplication(String packageName) {
+ Slog.w(TAG, "startApplication packageName " + packageName);
+ if (TextUtils.isEmpty(packageName)) {
+ return;
}
- Pattern p = Pattern.compile(IPRegExp);
- Matcher m = p.matcher(ip);
- return m.matches();
+ ApplicationInfo info = null;
+ try {
+ info = AppGlobals.getPackageManager().getApplicationInfo(packageName, 0, 0);
+ } catch (RemoteException e) {
+ }
+ Slog.w(TAG, "startApplication info " + info);
+ if (info != null) {
+ ProcessRecord app = getProcessRecordLocked(info.processName, info.uid, true);
+ if (app == null) {
+ app = newProcessRecordLocked(info, null, false, 0);
+ }
+ if (!mAutoStartAppList.contains(packageName)) {
+ mAutoStartAppList.add(packageName);
+ }
+
+
+ startProcessLocked(app, "added application", app.processName, null,
+ null , null );
+ }
+ }
+
+ private boolean isAutoStartApp(ProcessRecord app) {
+ String[] packages = app.getPackageList();
+ if (packages != null) {
+ for (int i = 0; i < packages.length; i++) {
+ if (mAutoStartAppList.contains(packages[i])) {
+ Log.d(TAG_MEMORY, "AutoStartAppList contains " + packages[i] + " return");
+ return true;
+ }
+ }
+ }
+ return false;
}
+
}
将需要快速启动的APP添加到 mAutoStartAppList,AMS中的killTargetProcessesLocked 用于动态调节adj值,如果isAutoStartApp 则不进行低内存回收或杀死。
|