【Android】点击应用进而打开base.apk的调用流程再分析
来源:互联网 发布:女生做春梦 知乎 编辑:程序博客网 时间:2024/05/16 05:55
点击一个应用的时候,会加载其对应的base.apk,我们在AssetManager类的addAssetPath方法中添加堆栈打印,
其调用堆栈为
android.content.res.AssetManager.addAssetPath(AssetManager.java:653)
android.app.ResourcesManager.getTopLevelResources(ResourcesManager.java:221)
android.app.ActivityThread.getTopLevelResources(ActivityThread.java:1854)
android.app.LoadedApk.getResources(LoadedApk.java:558)
android.app.ContextImpl.<init>(ContextImpl.java:1884)
android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1733)
android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1718)
com.android.server.AttributeCache.get(AttributeCache.java:114)
com.android.server.am.ActivityRecord.<init>(ActivityRecord.java:564)com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1763)
com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:1153)
com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4271)
com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:4258)
android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:168)
com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2703)
分析这个堆栈信息,我们来追根溯源的查看AssetManager对象的创建过程。
第一次打开应用的时候,调到ActivityManagerService的startActivityAsUser方法,
后来调到com.android.server.am.ActivityRecord.<init>(ActivityRecord.java:564)
564 AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
565 realTheme,com.android.internal.R.styleable.Window, userId);
继续调用
com.android.server.AttributeCache.get(AttributeCache.java:114)
查看AttributeCache.java
112 Context context;
113 try {
114 context =mContext.createPackageContextAsUser(packageName, 0,
115 new UserHandle(userId));
116 if (context == null) {
117 return null;
118 }
119 } catch (PackageManager.NameNotFoundExceptione) {
120 return null;
121 }
122 pkg = new Package(context);
123 mPackages.put(packageName, pkg);
在这里,mPackages是一个map,其定义为
private final WeakHashMap<String,Package> mPackages =
newWeakHashMap<String, Package>();
在Android 7上,修改为了
private finalArrayMap<String, WeakReference<Package>> mPackages = newArrayMap<>();
在114行,变量context指向了mContext.createPackageContextAsUser(packageName, 0, newUserHandle(userId));的返回值
在122行对context进行了引用。
114行调用到android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1718)
继续调用到
android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1733)
查看ContextImpl.java
1733 ContextImpl c = new ContextImpl(this,mMainThread, pi, mActivityToken,
1734 user, restricted, mDisplay, null,Display.INVALID_DISPLAY, themePackageName);
1733行又调用到
android.app.ContextImpl.<init>(ContextImpl.java:1884)
查看ContextImpl.java
1884 Resources resources =packageInfo.getResources(mainThread);
1906 mResources = resources;
新创建的ContextImpl对象的成员变量mResources对resources进行了引用。
1884行继续调用
android.app.LoadedApk.getResources(LoadedApk.java:558)
android.app.ActivityThread.getTopLevelResources(ActivityThread.java:1854)
android.app.ResourcesManager.getTopLevelResources(ResourcesManager.java:221)
查看ResourcesManager.java
211 AssetManager assets = newAssetManager();
218 // already.
219 if (resDir != null) {
220
221 if (assets.addAssetPath(resDir) ==0) {
222 return null;
223 }
224 }
301 r = new Resources(assets, dm, config,compatInfo);
319 return r;
终于,找到了AssetManager创建的地方了,然后创建了C++层的AssetManager对象,再调用addAssetPath方法加载了base.apk
在Resources.java中有
public Resources(AssetManager assets, DisplayMetrics metrics,Configuration config, CompatibilityInfocompatInfo) {
mAssets = assets;
mMetrics.setToDefaults();
if (compatInfo != null) {
mCompatibilityInfo = compatInfo;
}
updateConfiguration(config, metrics);
assets.recreateStringBlocks();//Modified for ThemeManager
}
Resources中的mAssets对新创建的AssetManager对象进行了引用- 【Android】点击应用进而打开base.apk的调用流程再分析
- Android Hello world程序再分析【Android程序的启动流程】
- 发布Android APK应用流程
- 发布Android APK应用流程
- 发布Android APK应用流程!
- 发布Android APK应用流程
- 发布Android APK应用流程
- cocos2dx:C++层通过JniHelper调用JAVA层代码进而调用Android手机应用接口
- android--实现通过点击链接打开apk(应用图标在桌面消失)
- Android 点击链接打开应用
- 函数调用过程再分析
- APK安装成功后点击"打开"再按Home键应用会重启的问题
- android 获取应用列表 点击打开应用
- Android 应用安装成功,点击“打开”和“完成”的区别
- Android 安装应用后点击打开带来的问题
- Android Wi-Fi 设置country code的调用流程(博通芯片为base)
- android根据包名打开apk应用
- android学习笔记12 - apk应用间的调用
- JSON的简介以及android 提供的JSON解析类
- Word自动生成书籍目录
- 负数的带符号和不带符号的移位运算
- python numpy包的使用一 基本操作
- Oracle(三)(数据查询)
- 【Android】点击应用进而打开base.apk的调用流程再分析
- Linux下的V4L2的编程总结
- 四元数和欧拉角学习
- jsp中文传递参数乱码。
- 编程题(懂二进制)
- Eclipse(pyDev)导入Anaconda2发行版中的模块
- asp.net中TreeView的使用
- 3.longest substring
- pcl 画法线