Android插件开发初探——基础篇

Android插件开发初探

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

为什么要插件化?

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

插件化的好处

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

插件化的要求

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

安装包的组成

需要安装的插件

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

  • 主应用可以以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) {
        }
    }
}

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

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

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

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

动态加载系统组件和资源

PluginLib

PluginHost

PluginTest

我们一个简单的插件框架就如下图所示:

主应用列出安装的Plugins,点击启动对应的PluginActivity

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

  • 可以基本完整实现一个Activity
  • 可以继续增加其他组件的插件,完成更多的功能(Service,Receiver,ContentProvider,Application?)

此插件机制的缺点

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

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

/*

* @author zhoushengtao(周圣韬)

* @since 2015年1月27日 上午14:02:22

* @weixin stchou_zst

* @blog http://blog.csdn.net/yzzst

* @交流学习QQ群:341989536

* @私人QQ:445914891

/

时间: 2024-10-09 22:21:45

Android插件开发初探——基础篇的相关文章

Android插件开发初探——分析篇

承接上文 Android插件开发初探--基础篇 http://blog.csdn.net/yzzst/article/details/45582315 我们通过使用DexClassLoader能够将classes.dex中的类动态的加载进入当前进程.当然,也就可以预先定一些代理的接口完成四大组件的功能. 整体功能如下图所示: 当然,对于一个Android的应用程序而言,只是动态的加载类与声明四大组件是不够的.如下图所示,使我们常见到的一个APK文件解压缩后的文件内容. 有过Android项目开发

Java(Android)线程池---基础篇

1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 newThread(newRunnable(){ 2 3 @Override 4 publicvoidrun(){ 5 // TODO Auto-generated method stub 6 } 7 }).start(); 那你就out太多了,new Thread的弊端如下: a. 每次new Thread新建对象性能差.b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致

Android应用开发基础篇(4)-----TabHost(选项卡)

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/18/2357093.html 一.概述 TabHost是一种用来显示标签的组件,不清楚?看一下来电通这个应用就知道了.这个组件用起来与其他组件不太一样,它需要继承TabActivity这个类,还有它的布局文件与我们平时用的也有些不一样. 二.要求 实现一个具有三个标签的选项卡,每个标签使用不同的布局作为内容,当切换不同的标签时向用户发出提示. 三.实现      声明:这个应用需要用到前面一篇

Android应用开发基础篇(3)-----ListView

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/16/2354625.html 一.概述 ListView是一个列表显示控件,它的应用非常广泛,在很多应用程序中都可以看到它的身影,比如来电通,网易新闻等等,特别是QQ.因此非常有必要熟练掌握它. 二.要求 能够利用ListView显示一些内容,如数据.文本,某一行被点击时有相应的提示:能够实现简单的ListView的动态插入和删除. 三.实现 新建工程MyListView,修改/res/lay

Android应用开发基础篇(12)-----Socket通信(转载)

转自:http://www.devdiv.com/android_socket_-blog-258060-10594.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络编程是非常有必要的,而我觉得socket编程是网络编程的基础.在进入正题之前,先介 绍几点网络知识,一:socket编程有分TCP和UDP两种,TCP是基于连接的,而UDP是无连接的:二:一个TCP连接包括了输入和输出两条独立的 路径:三:服务器必须先运行然后客户端才能与它进行通信.四:客户端与服务

Android应用开发基础篇(12)-----Socket通信

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378669.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络编程是非常有必要的,而我觉得socket编程是网络编程的基础.在进入正题之前,先介绍几点网络知识,一:socket编程有分TCP和UDP两种,TCP是基于连接的,而UDP是无连接的:二:一个TCP连接包括了输入和输出两条独立的路径:三:服务器必须先运行然后客户端才能与它进行通信.四:客户端与服

Eclipse插件开发之基础篇(1) 插件开发的基础知识

转载出处http://www.cnblogs.com/liuzhuo 名词翻译 有一些名词在翻译的过程中可能会出现歧义,在这里统一一下. アーキテクチャ=architecture=架构 プラットフォーム=platform=平台 コンポーネント=component=组件 其余的随时补充. 1.Eclipse的架构 Eclipse被作为java的IDE(集成开发环境)被广泛的应用,但是从本质上看Eclipse是一个整合了各种开发工具的平台.因此,它采用了可以自由的增加各种功能的插件架构技术.Ecli

[转]Eclipse插件开发之基础篇(1) 插件开发的基础知识

原文地址:http://www.cnblogs.com/liuzhuo/archive/2010/08/13/eclipse_plugin_1_0_2.html 名词翻译 有一些名词在翻译的过程中可能会出现歧义,在这里统一一下. アーキテクチャ=architecture=架构 プラットフォーム=platform=平台 コンポーネント=component=组件 其余的随时补充. 1.Eclipse的架构 Eclipse被作为java的IDE(集成开发环境)被广泛的应用,但是从本质上看Eclipse

Android笔记(五十七)Android总结:基础篇

什么是安卓 Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发.目前发行版本是6.0 安卓平台的优势 一.开放性       在优势方面,Android平台首先就是其开发性,开发的平台允许任何移动终端厂商加入到Android联盟中来.显著的开放性可以使其拥有更多的开发者,随着用户和应用的日益丰富,一个崭新的平台也将很快走向成熟.   二.挣脱运营商的束缚  在过去很长的一段时间,特别是在欧美地区,手