您的位置:首页 > 移动开发

Android App 启动流程理解

2016-04-25 15:17 519 查看
Launcher中通过app AndroidManifest.xml中<intent-filter ><action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER"
/> </intent-filter>配置的拦截决定是否在桌面显示,通过startActivity启动主Activity,App的启动可理解成Activity的启动。

App分为用户安装在data下的和系统app,比如system/app or system/priv-app但是这些apk都由frameworks
/base/services/core/java/com/android/server/pm/PackageManagerService.java管理,PackageManagerService.java在min函数中通过 ServiceManager.addService("package",
m);添加为系统服务,开机自启,第一次开机通过scanDirLI将系统apk进行解析,比如大随卡即是拦截控制App对于apk是否需要安装:

private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {

………….

for (File file : files) {

final boolean isPackage = (isApkFile(file) || file.isDirectory())

&& !PackageInstallerService.isStageName(file.getName());

if (!isPackage) {

// Ignore entries which are not packages

continue;

}

boolean NeedNotSetupFlag = false;

String apkFullName = file.getName();

//when we arrived here, APKName must be available

for (String str : apkNeedNotSetupList) {

if(apkFullName.equals(str)){

Log.d("caoxuhao", "don't setup this apk: " + str);

NeedNotSetupFlag = true;

break;

}

}

if(NeedNotSetupFlag){continue;}

/** M: Add PMS scan package time log @{ */

startScanTime = SystemClock.uptimeMillis();

Slog.d(TAG, "scan package: " + file.toString() + " , start at: " + startScanTime + "ms.");

/** @} */

try {

scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,

scanFlags, currentTime, null);

} catch (PackageManagerException e) {

Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());

// Delete invalid userdata apps

if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&

e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {

logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);

if (file.isDirectory()) {

FileUtils.deleteContents(file);

}

file.delete();

}

}

/** M: Add PMS scan package time log @{ */

endScanTime = SystemClock.uptimeMillis();

Slog.d(TAG, "scan package: " + file.toString() + " , end at: " + endScanTime + "ms. elapsed time = " + (endScanTime - startScanTime) + "ms.");

/** @} */

}

/// M: Mtprof tool

addBootEvent(new String("Android:PMS_scan_data_done:" + dir.getPath().toString()));

}

在PWS中将相应的AndroidManifest.xml关键信息解析保存到data/system /package.xml,该服务通过AppDirObserver一直监听系统App的状态,如果出现了安装和卸载操作后在更新package.xml

这样在启动的时候就能通过PMS获取要启动应用的包名类名,得到启动Activity的先决条件,startActivity最终ActivityManagerService.startActivity方法中执行的,所有Activity的管理核心是frameworks
/base/services/core/java/com/android/server/am/AcitivityManagerService,和PackageManagerService一样是一个独立的进程,每一个App的ActiveThread(UI线程)与AcitivityManagerService的通信是属于进程间通信,使用binder机制,

Copy了一张图,更清楚一些



一. Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;

二.ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;

三. Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,启动ActivityThread(包含main函数,启动相应的消息循环机制),即将要启动的Activity就是在这个ActivityThread实例中运行;

四. ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;

五. ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,ActivityThread在performLaunchActivity中通过ClassLoader启动相应Activity类进入app
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: