当前位置: 移动技术网 > 移动技术>移动开发>Android > Android中persistent属性用法详解

Android中persistent属性用法详解

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文实例讲述了android中persistent属性用法。分享给大家供大家参考,具体如下:

前段时间在研究telephony时,一直没有在framework下发现对telephony的初始化(phonefactory.java中的makedefaultphones函数)的调用。结果全局搜索之后发现在application phoneapp(packages/apps/phone)中调用了。但是application phoneapp既没有被broadcast唤醒,也没有被其他service调用,那么是android是通过什么方式来启动phoneapp,所以就发现了属性android:persistent。

在androidmanifest.xml定义中,application有这么一个属性android:persistent,根据字面意思来理解就是说该应用是可持久的,也即是常驻的应用。其实就是这么个理解,被android:persistent修饰的应用会在系统启动之后被am启动。

am首先去pm(packagemanagerservice)中去查找设置了android:persistent的应用

public void systemready(final runnable goingcallback) {
  if (mfactorytest != systemserver.factory_test_low_level) {
    try {
      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);
          }
        }
      }
    } catch (remoteexception ex) {
      // pm is in same process, this will never happen.
    }
  }
}

假如该被android:persistent修饰的应用此时并未运行的话,那么am将调用startprocesslocked启动该app,关于startprocesslocked不再描述,另外一篇文章《how to start a new process for android?》中做了详细的介绍(这篇英文文档小编就不翻译了,感兴趣的朋友可以搜到看一看)。

app的启动过程就是启动app所在的package对应的进程。

final processrecord addapplocked(applicationinfo info) {
    processrecord app = getprocessrecordlocked(info.processname, info.uid);
    if (app == null) {
      app = newprocessrecordlocked(null, info, null);
      mprocessnames.put(info.processname, info.uid, app);
      updatelruprocesslocked(app, true, true);
    }
    if ((info.flags&(applicationinfo.flag_system|applicationinfo.flag_persistent))
        == (applicationinfo.flag_system|applicationinfo.flag_persistent)) {
      app.persistent = true;
      app.maxadj = core_server_adj;
    }
    if (app.thread == null && mpersistentstartingprocesses.indexof(app) < 0) {
      mpersistentstartingprocesses.add(app);
      startprocesslocked(app, "added application", app.processname);
    }
    return app;
}

面介绍app所在的package对应的进程启动完成之后,app是如何被create的。

从文章《how to start a new process for android?》中可知,zygote在创建新的进程均会启动它的mainthread android.app.activitythread,因此我们从activitythread的main函数中接着分析app的create过程。

在main中有下面这个操作

thread.attach(false);

在attach过程中,activitythread会将对应的application attach到am中去,交与am去管理。这里需要注意一个变量

final applicationthread mappthread = new applicationthread();

mappthread是一个applicationthread对象,mappthread可以看作是当前进程主线程的核心,它负责处理本进程与其他进程(主要是am)之间的通信,同时通过attachapplication将mappthread的代理binder传递给am。

private final void attach(boolean system) {
    sthreadlocal.set(this);
    msystemthread = system;
    if (!system) {
      viewroot.addfirstdrawhandler(new runnable() {
        public void run() {
          ensurejitenabled();
        }
      });
      android.ddm.ddmhandleappname.setappname("<pre-initialized>");
      runtimeinit.setapplicationobject(mappthread.asbinder());
      iactivitymanager mgr = activitymanagernative.getdefault();
      try {
        mgr.attachapplication(mappthread);
      } catch (remoteexception ex) {
      }
    }
}

上面的attach代码中,我们顺着ipc调用am的attachapplication过程再往下看。
在该过程中,am调用到了ipc通信调用mappthread的bindapplication;

private final boolean attachapplicationlocked(iapplicationthread thread,
  int pid) {
  thread.bindapplication(processname, app.instrumentationinfo != null
      ? app.instrumentationinfo : app.info, providers,
      app.instrumentationclass, app.instrumentationprofilefile,
      app.instrumentationarguments, app.instrumentationwatcher, testmode,
      isrestrictedbackupmode || !normalmode,
      mconfiguration, getcommonserviceslocked());
  updatelruprocesslocked(app, false, true);
  app.lastrequestedgc = app.lastlowmemory = systemclock.uptimemillis();
}

mappthread的bindapplication再通过消息机制向activitythread自身维护的handler发送bind_application消息。下面看看activitythread自身维护的handler对消息bind_application的处理,最终会调用到handlebindapplication函数

你会发现在handlebindapplication函数中有这么一句

minstrumentation.callapplicationoncreate(app);

我们最终在绕了好大一圈之后,调用了app的oncreate函数来启动这个application。

ps:更多关于androidmanifest.xml配置项及其功能可参考本站在线工具:

android manifest功能与权限描述大全:

更多关于android相关内容感兴趣的读者可查看本站专题:《android数据库操作技巧总结》、《android编程之activity操作技巧总结》、《android文件操作技巧汇总》、《android编程开发之sd卡操作方法汇总》、《android开发入门与进阶教程》、《android资源操作技巧汇总》、《android视图view技巧总结》及《android控件用法总结

希望本文所述对大家android程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网