Android中persistent属性用法详解
本文实例讲述了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程序设计有所帮助。