Android Phone进程启动过程详解
2017-02-21 16:07
423 查看
之前解决一个开机搜网慢的问题时,发现由于Phone进程起来以后才会主动连接RILD,因而在一定程度上Phone进程启动的时间会影响网络状态注册的快慢。适当的将Phone进程提前,可以将网络注册时间提前一点,让状态栏中信号显示的时间提前。那么,Android中作为系统的核心进程之一,Phone进程是如何启动的了?
RIL运行机制请参考: http://blog.csdn.net/jason_wzn/article/details/53232022
Telephony最开始创建的是
那么,
那么,
打开Phone进程所在的源码路径:
在
android:persistent
Whether or not the application should remain running at all times — “true” if it should, and “false” if not. The default value is “false”. Applications should not normally set this flag; persistence mode is intended only for certain system applications.
由此可见,Phone应用是系统常驻进程,一旦起来后就会一直运行,不会被杀死。对于这类常驻进程,
启动所有
准备创建应用进程:
调用
发送消息到zygote的socket端口,请求创建新的进程:
这样Phone进程就创建启动完成了。整个流程看下来,研究Android系统,源码是王道,但要深入理解系统背后的设计,还是需要从把基本的概念梳理清楚,才能更好的理解系统背后设计的逻辑。
RIL运行机制请参考: http://blog.csdn.net/jason_wzn/article/details/53232022
Telephony最开始创建的是
PhoneFactory对象,直接搜索源码,可以看到在
PhoneGlobals.java创建时,会调用
PhoneFactory对Telephony进行初始化操作:
/** * Global state for the telephony subsystem when running in the primary * phone process. */ public class PhoneGlobals extends ContextWrapper { public void onCreate() { Log.v(LOG_TAG, "!@Boot_SVC : PhoneApp OnCrate"); // CallManager为空 if (mCM == null) { // Initialize the telephony framework PhoneFactory.makeDefaultPhones(this); // 创建CallManager实例 mCM = CallManager.getInstance(); for (Phone phone : PhoneFactory.getPhones()) { mCM.registerPhone(phone); } .... } }
那么,
PhoneGlobals又是在哪里创建的了?再次搜索代码,可以看到在同一文件目录下,有一个
PhoneApp.java文件:
@Override public void onCreate() { Log.d("PhoneApp", "onCreate"); if (UserHandle.myUserId() == 0) { // 创建PhoneGlobals实例 mPhoneGlobals = new PhoneGlobals(this); mPhoneGlobals.onCreate(); mTelephonyGlobals = new TelephonyGlobals(this); mTelephonyGlobals.onCreate(); } else { Log.d("PhoneApp", "Phone app is created as userid not 0, there's no PhoneApp() Instance"); } .... }
那么,
PhoneApp这个类又是什么时候创建的?我们知道,每一个Android应用都有一个
Application与之对应,它是在应用启动过程中创建的,但是在这里搜索所有的源码,也无法看到
PhoneApp创建的地方。实在想不出来,找了下度娘,才发现了真正启动Phone进程的地方。
打开Phone进程所在的源码路径:
/android/applications/sources/services/Telephony/,查看应用对应的
AndroidManefest.xml文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" package="com.android.phone" android:versionCode="1" android:versionName="1.0.0" coreApp="true" android:sharedUserId="android.uid.phone" android:sharedUserLabel="@string/phoneAppLabel" > ..... <application android:name="PhoneApp" android:persistent="true" android:hardwareAccelerated="true" android:label="@string/phoneAppLabel" android:icon="@mipmap/ic_launcher_phone" android:allowBackup="false" android:supportsRtl="true" android:usesCleartextTraffic="true" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true"> .... </application> </manifest>
在
application标签下面,可以看到
android:persistent="true"这个属性值,看一看官方的文档怎么解释的:
android:persistent
Whether or not the application should remain running at all times — “true” if it should, and “false” if not. The default value is “false”. Applications should not normally set this flag; persistence mode is intended only for certain system applications.
由此可见,Phone应用是系统常驻进程,一旦起来后就会一直运行,不会被杀死。对于这类常驻进程,
ActivityManagerService(以下简称AMS)会对其做特殊处理。在
SystemServer初始化完系统的核心服务后,其会调用AMS的
systemReady(Runnable r)函数:
public void systemReady(final Runnable goingCallback) { synchronized (this) { // Only start up encryption-aware persistent apps; once user is // unlocked we'll come back around and start unaware apps // 正是在这里,PhoneApp被创建! startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); // Start up initial activity. mBooting = true; // Enable home activity for system user, so that the system can always boot if (UserManager.isSplitSystemUser()) { ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); try { AppGlobals.getPackageManager().setComponentEnabledSetting(cName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, UserHandle.USER_SYSTEM); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } startHomeActivityLocked(currentUserId, "systemReady"); } }
启动所有
PackageManager.MATCH_DIRECT_BOOT_AWARE标志为
true的应用:
private void startPersistentApps(int matchFlags) { synchronized (this) { try { //获取系统所有常驻应用程序信息 final List<ApplicationInfo> apps = AppGlobals.getPackageManager() .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); for (ApplicationInfo app : apps) { if (!"android".equals(app.packageName)) { //加载应用 addAppLocked(app, false, null /* ABI override */); } } } catch (RemoteException ex) { } } } //添加应用程序进程到LRU列表中,并创建进程 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); updateLruProcessLocked(app, false, null); updateOomAdjLocked(); } .... if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { app.persistent = true; app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; } // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; //启动应用 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "added application", app.processName, abiOverride, null /* entryPoint */, null /* entryPointArgs */); } return app; }
准备创建应用进程:
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { Process.ProcessStartResult startResult = null; if(userid>0 && (bbcId>0 && userid == bbcId) && app.info.bbcseinfo!=null){ //启动进程 startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.bbcseinfo, app.info.bbccategory, app.info.accessInfo, requiredAbi, instructionSet, app.info.dataDir, mountKnoxPoint, entryPointArgs); }esle{ ... } }
调用
Process.start(),创建一个新的进程
ActivityThread,Phone进程就运行在该进程当中:
public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, int category, int accessInfo, String abi, String instructionSet, String appDataDir, boolean mountKnoxPoint, String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, category, accessInfo, abi, instructionSet, appDataDir, mountKnoxPoint, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); throw new RuntimeException( "Starting VM process through Zygote failed", ex); } }
发送消息到zygote的socket端口,请求创建新的进程:
private static ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, int category, int accessInfo, String abi, String instructionSet, String appDataDir, boolean mountKnoxPoint, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { ArrayList<String> argsForZygote = new ArrayList<String>(); // --runtime-args, --setuid=, --setgid=, // and --setgroups= must go first argsForZygote.add("--runtime-args"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); .... if (appDataDir != null) { argsForZygote.add("--app-data-dir=" + appDataDir); } .... argsForZygote.add(processClass); if (extraArgs != null) { for (String arg : extraArgs) { argsForZygote.add(arg); } } //发送消息到zygote的socket端口,请求创建新的进程 if (Zygote.isEnhancedZygoteASLREnabled) { .... return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); // End of isEnhancedZygoteASLREnabled case } else { // Original case return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } } }
这样Phone进程就创建启动完成了。整个流程看下来,研究Android系统,源码是王道,但要深入理解系统背后的设计,还是需要从把基本的概念梳理清楚,才能更好的理解系统背后设计的逻辑。
相关文章推荐
- 分析Android 根文件系统启动过程(init守护进程分析)
- Android 核心分析 之八------Android 启动过程详解
- Android应用程序进程启动过程(前篇)
- Android应用程序进程启动过程的源代码分析
- Android系统启动过程详解
- Android的学习之路(三)项目的启动过程和安装过程详解
- Android系统启动流程(一)解析init进程启动过程
- Android启动过程的Zygote进程
- 深入理解Dalvik虚拟机- Android进程启动过程
- Android 核心分析 之八------Android 启动过程详解
- 分析Android 根文件系统启动过程(init守护进程分析)
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- android启动过程详解(代码)
- Android系统进程Zygote启动过程的源代码分析
- 转 Android应用程序在新的进程中启动新的Activity的方法和过程分析 .
- 理解 Android 进程启动之全过程
- Android系统进程Zygote启动过程的源代码分析
- Android 核心分析 之八------Android 启动过程详解
- Linux-Android启动之zImage生成过程详解
- Android 启动过程详解