Android插件开发初探

对于Android的插件化其实已经讨论已久了,但是市面上还没有非常靠谱成熟的插件框架供我们使用。这里我们就尝试性的对比一下Java中,我们使用插件化该是一个怎么样的流程,且我们如何将此流程移植到Android框架上去使用。很多代码都是内部资料,不喜勿喷,谢谢~

为什么要插件化?

  • 功能越来越多
  • 代码、安装包越来越大
  • 小的更新也需要重新发布
  • 更新频繁,安装成本太大
  • 用户无法选择性加载需要的模块
  • ……

插件化的好处

  • 主安装包较小
  • 强制模块化,降低耦合度
  • 减少整体更新的次数
  • 插件可单独静默更新
  • 用户可以有所选择
  • ……

插件化的要求

  • 没有独立运行的入口
  • 主应用控制,下载、安装、删除、静默升级、打开和关闭
  • 主应用和插件资源共享

安装包的组成

Android插件开发初探——基础篇_第1张图片

需要安装的插件

对比一个安装包的组成,我们要处理的东西也就是很多:

  • 主应用可以以Intent方式启动具体的插件,同时带入Map类型参数或者json串参数
  • 使用相同的android:sharedUserId,资源数据共享
  • 根据sharedUserId来查找插件
  • queryIntentActivities查找符合这个action的所有activity(或其它)即插件
  • query方式可以获得插件的路径以及实现接口类的类名
  • 通过检索sharedUserId能够得到路径却无法获得到类名
  • 通常可以使用一个描述文件(xml、json)描述插件结构
  • createPackageContext()
  • getResourcesForApplication()

动态加载普通类
- Java 可以用 ClassLoader 动态加载.jar 中的Class文件,android可以吗?
- PathClassLoader
- DexClassLoader

接口类

    package com.plug;    public interface InterfacePlug {        public String function_01();        public int function_02(int a,int b);    }

实现类

import com.plug.InterfacePlug;    public class PlugImpl implements InterfacePlug{        @Override        public String function_01() {            return null;        }        @Override        public int function_02(int a, int b) {            return a+b;        }    }

主应用类

package com.host;    public class MyhostActivity extends Activity {        public void useDexClassLoader() {            DexClassLoader cDexClassLoader =                    new DexClassLoader("/mnt/sdcard/Myplugdex.jar", "/data/data/com.host", null, this.getClass()                            .getClassLoader());            try {                Class<?> class1 = cDexClassLoader.loadClass("com.plug.PlugImpl");                InterfacePlug interfacePlug = (InterfacePlug) class1.newInstance();                int ret = interfacePlug.function_02(12, 13);                tv.setText(" return value :" + ret);            } catch (Exception e) {            }        }    }

Android插件开发初探——基础篇_第2张图片

导出插件包时只能导出实现类,否则会出现

Classref in pre-verified class resolvedtounexpected implementation重复定义错误

当然,安装包的解析与插件安装远不止于类文件的加载,我们还需要:

  • 不是普通类怎么办?
  • 系统组件如何接收回调?
  • 如何加载资源?
  • PackageInfo处理?
  • Resources的处理?
  • Assets的处理?

动态加载系统组件和资源

PluginLib
Android插件开发初探——基础篇_第3张图片

PluginHost
Android插件开发初探——基础篇_第4张图片

PluginTest

Android插件开发初探——基础篇_第5张图片

我们一个简单的插件框架就如下图所示:
Android插件开发初探——基础篇_第6张图片

主应用列出安装的Plugins,点击启动对应的PluginActivity
Android插件开发初探——基础篇_第7张图片

当然,我们也可以根据此简单的机制来完成一个完整的插件系统。

  • 可以基本完整实现一个Activity

  • 可以继续增加其他组件的插件,完成更多的功能(Service,Receiver,ContentProvider,Application?)

此插件机制的缺点

  • Manifest中注册的信息由系统控制,因此插件需要权限信息需要预先注册在主程序中。
  • 目前实现有一定的限制,如插件宿主的相互调用、插件间的相互调用

Github上的插件框架,基于Fragment的开源插件框架

  • https://github.com/mmin18/AndroidDynamicLoader
  • UI基于Fragment
  • 反射得到Resources
  • 通过uri进行页面跳转

/*
* @author zhoushengtao(周圣韬)
* @since 2015年1月27日 上午14:02:22
* @weixin stchou_zst
* @blog http://blog.csdn.net/yzzst
* @交流学习QQ群:341989536
* @私人QQ:445914891
/

Android插件开发初探——基础篇_第8张图片

更多相关文章

  1. Android Tween动画之RotateAnimation实现图片不停旋转效果实例介
  2. Android中一张图片占用的内存大小
  3. [置顶] android中图片的三级cache策略(内存、文件、网络)之三:文件
  4. Android拖动和缩放图片
  5. [Android Studio 权威教程]Android Studio 三种添加插件的方式
  6. Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌
  7. Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果
  8. Android 基础知识(一)体系架构
  9. Android客户端如何从Web服务端加载图片

随机推荐

  1. 2011年Android手机用户购买行为研究报告
  2. Android布局优化之ViewStub(三)
  3. Android(安卓)Hierarchy Viewer
  4. Android——自定义View类(一 )
  5. Android打开APP会有权限询问
  6. 使用新版Android(安卓)Studio检测内存泄
  7. Android(安卓)系统中的 WatchDog 详解
  8. Android文件操作总结
  9. 关于Qt和android ndk的兼容问题
  10. Android(安卓)Handler