开发系统级应用不被Kill


一.设置方法
  (1) 在AndroidManifest中application根节点下,添加如下代码:
    android:persistent="true"
  (2) 将应用程序push到/system/app或/system/priv-app.
  重启之后就会看到效果,当系统将应用杀死之后会被立即重新启动.

二.persistent属性说明
  在Android系统中,有一种永久性利用。对应的AndroidManifest.xml文件里,将persistent属性设为true。
  这种应用会在系统未准备好时就启动,并在意外挂掉时被重新启动。

  1.在系统启动之时,ActivityManagerService的systemReady()会加载所有persistent为true的应用。看如下伪代码:    

        public void systemReady(final Runnable goingCallback) {
            ...
            List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);
            if (apps != null) {
                int N = apps.size();
                int i;
                for (i=0; i<N; i++) {
                    ApplicationInfo info= (ApplicationInfo)apps.get(i);
                    if (info != null && !info.packageName.equals("android")) {
                        addAppLocked(info, false, null /* ABI override */);
                    }
                }
            }
            ...
        }
        
        // The flags that are set for all calls we make to the package manager.
        static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
        
        public List<ApplicationInfo> getPersistentApplications(int flags) {
            final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
            // reader
            synchronized (mPackages) {
                final Iterator<PackageParser.Package> i = mPackages.values().iterator();
                final int userId = UserHandle.getCallingUserId();
                while (i.hasNext()) {
                    final PackageParser.Package p = i.next();
                    if (p.applicationInfo != null
                            && (p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
                            && (!mSafeMode || isSystemApp(p))) {
                        PackageSetting ps = mSettings.mPackages.get(p.packageName);
                        if (ps != null) {
                            ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
                                    ps.readUserState(userId), userId);
                            if (ai != null) {
                                finalList.add(ai);
                            }
                        }
                    }
                }
            }
            return finalList;
        }
        
        final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
            String abiOverride) {
            ProcessRecord app;
            if (!isolated) {
                app = getProcessRecordLocked(info.processName, info.uid, true);
            } else {
                app = null;
            }

            if (app == null) {
                app = newProcessRecordLocked(info, null, isolated, 0);
                mProcessNames.put(info.processName, app.uid, app);
                if (isolated) {
                    mIsolatedProcesses.put(app.uid, app);
                }
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }

            // This package really, really can not be stopped.
            try {
                AppGlobals.getPackageManager().setPackageStoppedState(
                        info.packageName, false, UserHandle.getUserId(app.uid));
            } catch (RemoteException e) {
            } catch (IllegalArgumentException e) {
                Slog.w(TAG, "Failed trying to unstop package "
                        + info.packageName + ": " + e);
            }

            if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
                    == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
                app.persistent = true;
                app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
            }
            if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
                mPersistentStartingProcesses.add(app);
                startProcessLocked(app, "added application", app.processName, abiOverride,
                        null /* entryPoint */, null /* entryPointArgs */);
            }

            return app;
        }

 

  在systemReady中,调用getPersistentApplications取得带有persistent标志的应用(flags中设置了FLAG_PERSISTENT),
  然后调用addAppLocked函数处理包名中不为android的应用。addAppLocked检查应用是否启动,没有启动时启动这个进程,
  因此配置了persistent标志的应用会在系统启动时启动。

  2.ActivityManagerService会对persistent标志的应用注册监听器: 

        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) {
            ...
            AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
            ...
        }

 


  一旦应用挂掉时检测到,并尝试重新启动。

  3.persistent应用可以在系统未准备好时启动:

        boolean isAllowedWhileBooting(ApplicationInfo ai) 
        {
            return (ai.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
        }

 



posted @ 2016-05-12 16:56  阿Hai  阅读(773)  评论(0编辑  收藏  举报