欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中persistent属性用法详解

程序员文章站 2024-03-04 20:05:24
本文实例讲述了android中persistent属性用法。分享给大家供大家参考,具体如下: 前段时间在研究telephony时,一直没有在framework下发现对te...

本文实例讲述了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功能与权限描述大全:
http://tools.jb51.net/table/androidmanifest

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

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