Android插件化学习之路(五)之代理Activity
2016-11-20 10:22
357 查看
简单模式中,使用ClassLoader加载外部的Dex或Apk文件,可以加载一些本地APP不存在的类,从而执行一些新的代码逻辑。但是使用这种方法却不能直接启动插件里的Activity。
使用插件APK里的Activity需要解决两个问题:
1. 如何使插件APK里的Activity具有生命周期;
2. 如何使插件APK里的Activity具有上下文环境(使用R资源);
代理Activity模式为解决这两个问题提供了一种思路。
ProxyActivity + 没注册的Activity = 标准的Activity
第二个问题,我们在上一篇博客中已经解决了,下面我们来分析使插件APK里的Activity具有生命周期的问题
那我们可以在主项目里创建一个ProxyActivity,再由它去代理调用插件Activity的生命周期方法(这也是代理模式叫法的由来)。用ProxyActivity(一个标准的Activity实例)的生命周期同步控制插件Activity(普通类的实例)的生命周期,同步的方式可以有下面两种:
• 在ProxyActivity生命周期里用反射调用插件Activity相应生命周期的方法,简单粗暴。
• 把插件Activity的生命周期抽象成接口,在ProxyActivity的生命周期里调用。另外,多了这一层接口,也方便主项目控制插件Activity。
用反射调用插件Activity相应生命周期
我们要在代理activity中去反射apk中activity的所有生命周期的方法,然后将activity的生命周期和代理activity的生命周期进行同步。首先,反射activity生命周期的所有方法,还反射了onActivityResult这个方法,尽管它不是典型的生命周期方法,但是它很有用。
其次,同步生命周期,主要看一下onResume和onPause,其他方法是类似的。看如下代码,很好理解,就是当系统调用代理activity生命周期方法的时候,就通过反射去显式调用apk中activity的对应方法。
把插件Activity的生命周期抽象成接口,在ProxyActivity的生命周期里调用
采用反射去管理activity的生命周期,这样存在一些不便,比如反射代码写起来复杂,并且过多使用反射有一定的性能开销。针对这个问题,可以采用接口机制,将activity的大部分生命周期方法提取出来作为一个接口(DLPlugin),然后通过代理activity(DLProxyActivity)去调用插件activity实现的生命周期方法,这样就完成了插件activity的生命周期管理,并且没有采用反射,当我们想增加一个新的生命周期方法的时候,只需要在接口中声明一下同时在代理activity中实现一下即可.
在代理类DLProxyActivity中的实现
通过以上两种方式,就可以解决插件Activity的生命周期的问题,现在一般推荐第二种方式。
参考文章:http://blog.csdn.net/singwhatiwanna/article/details/23387079
启动插件中Activity的两个主要问题
Activity等组件是需要在Manifest中注册后才能以标准Intent的方式启动的,通过ClassLoader加载并实例化的Activity实例只是一个普通的Java对象,能调用对象的方法,但是它没有生命周期,而且Activity等系统组件是需要Android的上下文环境的(Context等资源),没有这些东西Activity根本无法工作。使用插件APK里的Activity需要解决两个问题:
1. 如何使插件APK里的Activity具有生命周期;
2. 如何使插件APK里的Activity具有上下文环境(使用R资源);
代理Activity模式为解决这两个问题提供了一种思路。
代理Activity模式
这种模式的特点是:主项目APK注册一个代理Activity(命名为ProxyActivity),ProxyActivity是一个普通的Activity,但只是一个空壳,自身并没有什么业务逻辑。每次打开插件APK里的某一个Activity的时候,都是在主项目里使用标准的方式启动ProxyActivity,再在ProxyActivity的生命周期里同步调用插件中的Activity实例的生命周期方法,从而执行插件APK的业务逻辑。ProxyActivity + 没注册的Activity = 标准的Activity
第二个问题,我们在上一篇博客中已经解决了,下面我们来分析使插件APK里的Activity具有生命周期的问题
处理插件Activity的生命周期
目前还真的没什么办法能够处理这个问题,一个Activity的启动,如果不采用标准的Intent方式,没有经历过Android系统Framework层级的一系列初始化和注册过程,它的生命周期方法是不会被系统调用的(除非你能够修改Android系统的一些代码,而这已经是另一个领域的话题了,这里不展开)。那我们可以在主项目里创建一个ProxyActivity,再由它去代理调用插件Activity的生命周期方法(这也是代理模式叫法的由来)。用ProxyActivity(一个标准的Activity实例)的生命周期同步控制插件Activity(普通类的实例)的生命周期,同步的方式可以有下面两种:
• 在ProxyActivity生命周期里用反射调用插件Activity相应生命周期的方法,简单粗暴。
• 把插件Activity的生命周期抽象成接口,在ProxyActivity的生命周期里调用。另外,多了这一层接口,也方便主项目控制插件Activity。
用反射调用插件Activity相应生命周期
我们要在代理activity中去反射apk中activity的所有生命周期的方法,然后将activity的生命周期和代理activity的生命周期进行同步。首先,反射activity生命周期的所有方法,还反射了onActivityResult这个方法,尽管它不是典型的生命周期方法,但是它很有用。
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. 21. Method onCreate = null; 22. try { 23. onCreate = localClass.getDeclaredMethod("onCreate", new Class[] { Bundle.class }); 24. onCreate.setAccessible(true); 25. } catch (NoSuchMethodException e) { 26. e.printStackTrace(); 27. } 28. mActivityLifecircleMethods.put("onCreate", onCreate); 29. 30. Method onActivityResult = null; 31. try { 32. onActivityResult = localClass.getDeclaredMethod("onActivityResult", 33. new Class[] { int.class, int.class, Intent.class }); 34. onActivityResult.setAccessible(true); 35. } catch (NoSuchMethodException e) { 36. e.printStackTrace(); 37. } 38. mActivityLifecircleMethods.put("onActivityResult", onActivityResult); 39. }
其次,同步生命周期,主要看一下onResume和onPause,其他方法是类似的。看如下代码,很好理解,就是当系统调用代理activity生命周期方法的时候,就通过反射去显式调用apk中activity的对应方法。
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. } 12. } 13. 14. @Override 15. protected void onPause() { 16. Method onPause = mActivityLifecircleMethods.get("onPause"); 17. if (onPause != null) { 18. try { 19. onPause.invoke(mRemoteActivity, new Object[] { }); 20. } catch (Exception e) { 21. e.printStackTrace(); 22. } 23. } 24. super.onPause(); 25. }
把插件Activity的生命周期抽象成接口,在ProxyActivity的生命周期里调用
采用反射去管理activity的生命周期,这样存在一些不便,比如反射代码写起来复杂,并且过多使用反射有一定的性能开销。针对这个问题,可以采用接口机制,将activity的大部分生命周期方法提取出来作为一个接口(DLPlugin),然后通过代理activity(DLProxyActivity)去调用插件activity实现的生命周期方法,这样就完成了插件activity的生命周期管理,并且没有采用反射,当我们想增加一个新的生命周期方法的时候,只需要在接口中声明一下同时在代理activity中实现一下即可.
public interface DLPlugin { public void onStart(); public void onRestart(); public void onActivityResult(int requestCode, int resultCode, Intent data); public void onResume(); public void onPause(); public void onStop(); public void onDestroy(); public void onCreate(Bundle savedInstanceState); public void setProxy(Activity proxyActivity, String dexPath); public void onSaveInstanceState(Bundle outState); public void onNewIntent(Intent intent); public void onRestoreInstanceState(Bundle savedInstanceState); public boolean onTouchEvent(MotionEvent event); public boolean onKeyUp(int keyCode, KeyEvent event); public void onWindowAttributesChanged(LayoutParams params); public void onWindowFocusChanged(boolean hasFocus);
在代理类DLProxyActivity中的实现
... @Override protected void onStart() { mRemoteActivity.onStart(); super.onStart(); } @Override protected void onRestart() { mRemoteActivity.onRestart(); super.onRestart(); } @Override protected void onResume() { mRemoteActivity.onResume(); super.onResume(); } @Override protected void onPause() { mRemoteActivity.onPause(); super.onPause(); } @Override protected void onStop() { mRemoteActivity.onStop(); super.onStop(); } ...
通过以上两种方式,就可以解决插件Activity的生命周期的问题,现在一般推荐第二种方式。
参考文章:http://blog.csdn.net/singwhatiwanna/article/details/23387079
相关文章推荐
- Android插件化学习之路(五)之代理Activity
- Android插件化学习之路(六)之动态创建Activity
- Android开发学习之路--插件化基础动态代理Hook
- Android学习之路——Android四大组件之activity(二)数据的传递
- android开发学习之路(1)---- activity及intent基本详解(2)
- Android开发学习之路-回调实现Service向activity传递数据
- Android插件化学习之路(一)之动态加载综述
- Android学习之路------activity的四种启动模式分析
- Android学习之路——Android四大组件之activity(二)数据的传递
- Android开发学习之路--Activity之Intent
- Android学习之路之activity声明
- Android开发学习之路--Activity之生命周期
- 记android学习之路----Activity(3)
- Android 学习之路一:Activity之间传递数据的四种方式
- Android学习之路---Activity四种启动模式
- Android学习之路十一:Activity
- Android之路:Activity的学习
- Android开发学习之路-Service和Activity的通信
- Android开发学习之路--Activity之初体验
- 记android学习之路----Activity(1)