-
public final int addAssetPath(String path) {
-
int res = addAssetPathNative(path);
-
return res;
-
}
其次是要实现那两个抽象方法
[java] view plain copy
-
@Override
-
public AssetManager getAssets() {
-
return mAssetManager == null ? super.getAssets() : mAssetManager;
-
}
-
@Override
-
public Resources getResources() {
-
return mResources == null ? super.getResources() : mResources;
-
}
okay,问题搞定。这样一来,在apk中就可以通过R来访问资源了。
这是本文开头提到的另一个需要解决的难题。为什么会有这个问题,其实很好理解,apk被宿主程序调起以后,apk中的activity其实就是一个普通的对象,不具有activity的性质,因为系统启动activity是要做很多初始化工作的,而我们在应用层通过反射去启动activity是很难完成系统所做的初始化工作的,所以activity的大部分特性都无法使用包括activity的生命周期管理,这就需要我们自己去管理。谈到activity生命周期,其实就是那几个常见的方法:onCreate、onStart、onResume、onPause等,由于apk中的activity不是真正意义上的activity(没有在宿主程序中注册且没有完全初始化),所以这几个生命周期的方法系统就不会去自动调用了。针对此类问题,采用Fragment是一个不错的方法,Fragment从3.0引入,通过support-v4包,可以兼容3.0以下的android版本。Fragment既有类似于Activity的生命周期,又有类似于View的界面,将Fragment加入到Activity中,activity会自动管理Fragment的生命周期,通过第一篇文章我们知道,apk中的activity是通过宿主程序中的代理activity启动的,将Fragment加入到代理activity内部,其生命周期将完全由代理activity来管理,但是采用这种方法,就要求apk尽量采用Fragment来实现,还有就是在做页面跳转的时候有点麻烦,当然关于Fragment相关的内容我将在后面再做研究,本文不采用Fragment而是通过反射去手动管理activity的生命周期。
我们要在代理activity中去反射apk中activity的所有生命周期的方法,然后将activity的生命周期和代理activity的生命周期进行同步。首先,反射activity生命周期的所有方法,还反射了onActivityResult这个方法,尽管它不是典型的生命周期方法,但是它很有用。
[java] view plain copy
-
protected void instantiateLifecircleMethods(Class<?> localClass) {
-
String[] methodNames = new String[] {
-
“onRestart”,
-
“onStart”,
-
“onResume”,
-
“onPause”,
-
“onStop”,
-
“onDestory”
-
};
-
for (String methodName : methodNames) {
-
Method method = null;
-
try {
-
method = localClass.getDeclaredMethod(methodName, new Class[] { });
-
method.setAccessible(true);
-
} catch (NoSuchMethodException e) {
-
e.printStackTrace();
-
}
-
mActivityLifecircleMethods.put(methodName, method);
-
}
-
Method onCreate = null;
-
try {
-
onCreate = localClass.getDeclaredMethod(“onCreate”, new Class[] { Bundle.class });
-
onCreate.setAccessible(true);
-
} catch (NoSuchMethodException e) {
-
e.printStackTrace();
-
}
-
mActivityLifecircleMethods.put(“onCreate”, onCreate);
-
Method onActivityResult = null;
-
try {
-
onActivityResult = localClass.getDeclaredMethod(“onActivityResult”,
-
new Class[] { int.class, int.class, Intent.class });
-
onActivityResult.setAccessible(true);
-
} catch (NoSuchMethodException e) {
-
e.printStackTrace();
-
}
-
mActivityLifecircleMethods.put(“onActivityResult”, onActivityResult);
-
}
其次,同步生命周期,主要看一下onResume和onPause,其他方法是类似的。看如下代码,很好理解,就是当系统调用代理activity生命周期方法的时候,就通过反射去显式调用apk中activity的对应方法。
[java] view plain copy
-
@Override
-
protected void onResume() {
-
super.onResume();
-
Method onResume = mActivityLifecircleMethods.get(“onResume”);
-
if (onResume != null) {
-
try {
-
onResume.invoke(mRemoteActivity, new Object[] { });
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
@Override
-
protected void onPause() {
-
Method onPause = mActivityLifecircleMethods.get(“onPause”);
-
if (onPause != null) {
-
try {
-
onPause.invoke(mRemoteActivity, new Object[] { });
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
super.onPause();
-
}
文章开头提到,要想成为一个插件apk,是要满足一定条件的,如下是采用本文机制开发插件apk所需要遵循的规范:
1. 不能用this:因为this指向的是当前对象,即apk中的activity,但是由于activity已经不是常规意义上的activity,所以this是没有意义的。
2. 使用that:既然this不能用,那就用that,that是apk中activity的基类BaseActivity中的一个成员,它在apk安装运行的时候指向this,而在未安装的时候指向宿主程序中的代理activity,anyway,that is better than this。
3. 不能直接调用activity的成员方法:而必须通过that去调用,由于that的动态分配特性,通过that去调用activity的成员方法,在apk安装以后仍然可以正常运行。
4. 启动新activity的约束:启动外部activity不受限制,启动apk内部的activity有限制,首先由于apk中的activity没注册,所以不支持隐式调用,其次必须通过BaseActivity中定义的新方法startActivityByProxy和startActivityForResultByProxy,还有就是不支持LaunchMode。
5. 目前暂不支持Service、BroadcastReceiver等需要注册才能使用的组件。
1. DLIntent的定义,通过自定义的intent,来完成activity的无约束调起
2. 采用Fragment的生命周期管理
3. Service、BroadcastReceiver等组件的调起
4. 性能优化
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
578883)]
[外链图片转存中…(img-yQiEWSjO-1714948578884)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!