android 应用动态加载机制2--资源加载机制和Activity生命周期管理

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

完整开源地址:https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF

  1. addAssetPath.invoke(assetManager, mDexPath);

  2. mAssetManager = assetManager;

  3. } catch (Exception e) {

  4. e.printStackTrace();

  5. }

  6. Resources superRes = super.getResources();

  7. mResources = new Resources(mAssetManager, superRes.getDisplayMetrics(),

  8. superRes.getConfiguration());

  9. mTheme = mResources.newTheme();

  10. mTheme.setTo(super.getTheme());

  11. }

说明:加载的方法是通过反射,通过调用AssetManager中的addAssetPath方法,我们可以将一个apk中的资源加载到Resources中,由于addAssetPath是隐藏api我们无法直接调用,所以只能通过反射,下面是它的声明,通过注释我们可以看出,传递的路径可以是zip文件也可以是一个资源目录,而apk就是一个zip,所以直接将apk的路径传给它,资源就加载到AssetManager中了,然后再通过AssetManager来创建一个新的Resources对象,这个对象就是我们可以使用的apk中的资源了,这样我们的问题就解决了。

[java]  view plain  copy

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. /**

  2. * Add an additional set of assets to the asset manager.  This can be

  3. * either a directory or ZIP file.  Not for use by applications.  Returns

  4. * the cookie of the added asset, or 0 on failure.

  5. * {@hide}

  6. */

  7. public final int addAssetPath(String path) {

  8. int res = addAssetPathNative(path);

  9. return res;

  10. }

其次是要实现那两个抽象方法

[java]  view plain  copy

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. @Override

  2. public AssetManager getAssets() {

  3. return mAssetManager == null ? super.getAssets() : mAssetManager;

  4. }

  5. @Override

  6. public Resources getResources() {

  7. return mResources == null ? super.getResources() : mResources;

  8. }

okay,问题搞定。这样一来,在apk中就可以通过R来访问资源了。

activity生命周期的管理


这是本文开头提到的另一个需要解决的难题。为什么会有这个问题,其实很好理解,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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. protected void instantiateLifecircleMethods(Class<?> localClass) {

  2. String[] methodNames = new String[] {

  3. “onRestart”,

  4. “onStart”,

  5. “onResume”,

  6. “onPause”,

  7. “onStop”,

  8. “onDestory”

  9. };

  10. for (String methodName : methodNames) {

  11. Method method = null;

  12. try {

  13. method = localClass.getDeclaredMethod(methodName, new Class[] { });

  14. method.setAccessible(true);

  15. } catch (NoSuchMethodException e) {

  16. e.printStackTrace();

  17. }

  18. mActivityLifecircleMethods.put(methodName, method);

  19. }

  20. Method onCreate = null;

  21. try {

  22. onCreate = localClass.getDeclaredMethod(“onCreate”, new Class[] { Bundle.class });

  23. onCreate.setAccessible(true);

  24. } catch (NoSuchMethodException e) {

  25. e.printStackTrace();

  26. }

  27. mActivityLifecircleMethods.put(“onCreate”, onCreate);

  28. Method onActivityResult = null;

  29. try {

  30. onActivityResult = localClass.getDeclaredMethod(“onActivityResult”,

  31. new Class[] { int.class, int.class, Intent.class });

  32. onActivityResult.setAccessible(true);

  33. } catch (NoSuchMethodException e) {

  34. e.printStackTrace();

  35. }

  36. mActivityLifecircleMethods.put(“onActivityResult”, onActivityResult);

  37. }

其次,同步生命周期,主要看一下onResume和onPause,其他方法是类似的。看如下代码,很好理解,就是当系统调用代理activity生命周期方法的时候,就通过反射去显式调用apk中activity的对应方法。

[java]  view plain  copy

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. @Override

  2. protected void onResume() {

  3. super.onResume();

  4. Method onResume = mActivityLifecircleMethods.get(“onResume”);

  5. if (onResume != null) {

  6. try {

  7. onResume.invoke(mRemoteActivity, new Object[] { });

  8. } catch (Exception e) {

  9. e.printStackTrace();

  10. }

  11. }

nResume != null) {

  1. try {

  2. onResume.invoke(mRemoteActivity, new Object[] { });

  3. } catch (Exception e) {

  4. e.printStackTrace();

  5. }

  6. }

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值