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
/> </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
相关文章推荐
- Jenkins Android 自动打包配置
- 上传AppStore遇到的坑
- Android中的内存管理机制以及正确的使用方式
- 清除WKWebView cookies
- Android方法记录
- cocos2d-C++ 学习UI控件(三)之 LoadingBar|ScrollView
- 网易云音乐App(iOS)分析
- Exception in thread "main" java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z)V解决办法
- Android中文API-Include标签
- iOS开发需要哪些图片?
- android /Cordova LOG 、console 调试调试打印log
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)
- iOS 不建议使用PCH文件-----使用PCH文件的坏处
- 关于Activity生命周期的理解 一(直白高效版)
- iOS中使用RSA加密
- 好文!关于iOS下的正则表达式实战案例
- 好文!关于iOS下的正则表达式实战案例
- Android studio 使用技巧以及常用设置
- android自定义view----等分饼图,实现每个块中间的间隔
- Android关于OnTouch 和OnClick同时调用冲突的解决方案