栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

实战-Android一种快速启动实现方案

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

实战-Android一种快速启动实现方案

需求
进入系统后,用户进入一些经常使用的应用,可以快速打开,类似于之前已经打开过,然后,可以快速进入应用界面。

实现
1.前端机器,上报应用的使用频率&使用时间到后台
2.后台利用前端的上报,采用一定的策略(比如用户经常使用的应用& 根据用户的使用频率,预测用户将要使用的应用等),下发需要快速启动的应用列表
3.前端接收到快速启动应用列表,在系统启动阶段,直接准备好应用程序的进程,但是不直接拉起应用程序的Activity(注意,只是准备好进程),从而达到后续启动应用程序时,不需要准备进程启动的阶段,直接启动Activity。
4.AMS中维护一个列表,低内存回收针对这个快速启动列表的,直接忽略

Coding

private void startProcess(List 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 {
     //Fun.tv Begin kill linux native process by pids
     public void killNativeProcess(int[] pids) throws RemoteException;
     //Fun.tv End kill linux native process by pids
+
+    // Begin fun.tv add for start process
+    public void startApplication(String packageName) throws RemoteException;
+    // End fun.tv add for start process
+
     
@@ -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
     }
     //Fun.tv End memory black & white list

+    private List mAutoStartAppList = new ArrayList();
+
     //Fun.tv Begin kill Linux process by pids
     @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()) {  // only do this in main looper
             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;
+
+    // Begin fun.tv add for start process
+    @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);
+            }
+            //app.curAdj = ProcessList.FOREGROUND_APP_ADJ;
+
+            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;
     }
+    // End fun.tv add for start process
 }

将需要快速启动的APP添加到 mAutoStartAppList,AMS中的killTargetProcessesLocked 用于动态调节adj值,如果isAutoStartApp 则不进行低内存回收或杀死。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/672254.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号