Android开发组件化与插件化详解

什么是组件化?通俗易懂来讲就是,拆成多个module开发就是组件化 。
什么是插件化?App的部分功能模块在打包时并不以传统?式打包进apk?件中,?是以另?种形式?次封装进apk内部,或者放在?络上适时下载,在需要的时候动态对这些功能模块进?加载,称之为插件化 。这些单独?次封装的功能模块apk,就称作插件,初始安装的apk称作宿主 。插件化是组件化的更进?步推进 。
插件化基础之反射:反射的写法try {Class utilClass = Class.forName("com.hencoder.demo.hidden.Util");Constructor utilConstructor = utilClass.getDeclaredConstructors()[0];utilConstructor.setAccessible(true);Object util = utilConstructor.newInstance();Method shoutMethod = utilClass.getDeclaredMethod("shout");shoutMethod.setAccessible(true);shoutMethod.invoke(util);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}反射的目的JAVA既然提供了可?性关键字public、private等等,?来限制代码之间的可?性,为什么?要提供反射功能?可?性特性的?持不是为了代码不被坏?使?,?是为了程序开发的简洁性 。安全性的话,可?性的?持提供的是Safety
的安全,?不是Security的安全 。即,可?性的?持让程序更不容易写出bug,?不是更不容易被??侵 。反射的?持可以让开发者在可?性的例外场景中,可以突破可?性限制来调???需要的API 。这是基于对开发者在使?反射时已经?够了解和谨慎的假设的 。所以,可?性的?持不是为了防御外来者?侵,因此反射功能的?持并没有什么不合理 。
关于DEX:

  • class:java编译后的?件,每个类对应?个class?件
  • dex:Dalvik EXecutable把class打包在?起,?个dex可以包含多个class?件
  • odex:Optimized DEX针对系统的优化,例如某个?法的调?指令,会把虚拟的调?转换为使?具体的index,这样在执?的时候就不?再查找了
  • oat:Optimized Androidfile Type 。使?AOT策略对dex预先编译(解释)成本地指令,这样再运?阶段就不需再经历?次解释过程,程序的运?可以更快
  • AOT:Ahead-Of-Time compilation预先编译
插件化原理:动态加载通过?定义ClassLoader来加载新的dex?件,从?让程序员原本没有的类可以被使?,这就是插件化的原理 。例如:把Utils拆到单独的项?,打包apk作为插件引?:
File f = new File(getCacheDir() + "/demo-debug.apk");if (!f.exists()) {try {InputStream is = getAssets().open("apk/demo-debug.apk");int size = is.available();byte[] buffer = new byte[size];is.read(buffer);is.close();FileOutputStream fos = new FileOutputStream(f);fos.write(buffer);fos.close();} catch (Exception e) {throw new RuntimeException(e);}}DexClassLoader classLoader = new DexClassLoader(f.getPath(),getCodeCacheDir().getPath(), null, null);try {Class oldClass = classLoader.loadClass("com.hencoder.demo.hidden.Util");Constructor utilConstructor = oldClass.getDeclaredConstructors()[0];utilConstructor.setAccessible(true);Object util = utilConstructor.newInstance();Method shoutMethod = oldClass.getDeclaredMethod("shout");shoutMethod.setAccessible(true);shoutMethod.invoke(util);Class activityClass = classLoader.loadClass("com.hencoder.demo.MainActivity");startActivity(new Intent(this, activityClass));} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}问题?:未注册的组件(例如Activity)不能打开
  • 解决?式?:代理Activity
  • 解决?式?:欺骗系统
  • 解决?式三:重写gradle打包过程,合并AndroiManifest.xml
问题?:资源?件?法加载解决?式:?定义AssetManager和Resources对象
private AssetManager createAssetManager (String dexPath) {try {AssetManager assetManager = AssetManager.class.newInstance();Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);addAssetPath.invoke(assetManager, dexPath);return assetManager;} catch (Exception e) {e.printStackTrace();return null;}}插件化有什么用?