文档章节

Android 插件开发

Kerison
 Kerison
发布于 2014/10/08 14:55
字数 569
阅读 21
收藏 1

简介

DexClassLoader 是Android系统中特有的类加载器,其父类为ClassLoader,插件开发主要就是利用了DexClassLoader来实现动态加载类,以便实现动态切换各种功能。

实践

  1. 首先一般开发是提供Service的通用接口。此处为CommonService.java ,可导出jar以方便为其他人使用【PluginService.jar】。

public interface CommonService {
	/**
	 * say Hello
	 */
	public void sayHello();

	/**
	 * get sum
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public int add(int a, int b);
}

2.新建一个Application,实现上述接口,可为普通java jar包插件(只是业务),也可以为apk应用插件(主题,资源等)。

public class ServiceImpl implements CommonService {

	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		Log.e("ServiceImpl", "sayHello");
	}

	@Override
	public int add(int a, int b) {
		// TODO Auto-generated method stub
		return a+b;
	}
}

并修改应用程序配置文件中如下
        <activity
            android:name="xx.xx.plugin.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="xx.xx.plugin_1.ACTION" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

3.在自己的主程序中导入PluginService.jar

/**
	 * 定义一个插件的Action
	 */
	public static final String PLUGIN_1_ACTION = "xx.xx.plugin_1.ACTION";
	
    	protected void onPluginLoading() {
    		// 创建一个查找apk意图
    		Intent intent = new Intent(PLUGIN_1_ACTION, null);
    		// 获得应用程序包名
    		PackageManager pm = getPackageManager();
    		List<ResolveInfo> resolveinfoes = pm.queryIntentActivities(intent, 0);
    		ActivityInfo actInfo = resolveinfoes.get(0).activityInfo;
    		String pacageName = actInfo.packageName;
    		
    		// 获得apk的目录或者jar的文件Path
    		String apkPath = actInfo.applicationInfo.sourceDir;
    		
    		//解压后的目录  一般在/data/data/XXXX 自己的私有程序包内
    		String dexOutputDir = getApplicationInfo().dataDir;
    		// native代码的目录
    		String libPath = actInfo.applicationInfo.nativeLibraryDir;
    
    		// 创建dex类加载器
    		DexClassLoader classLoader = new DexClassLoader(apkPath, dexOutputDir,
    				libPath, getClassLoader());
    		// 利用反射调用插件包内的类的方法
    		try {
    			String className = pacageName+".ServiceImpl";
    			Class<?> clazz = Class.forName(className, true, classLoader);
    			// Class<?> clazz = classLoader.loadClass(className);
    			CommonService obj = (CommonService) clazz.newInstance();
    
    			obj.sayHello();
    			Log.e("Host", "return result is " + obj.add(1, 13));
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
	}

先安装apk插件或copy jar文件到制定目录,然后再运行主程序,结果如下:


注意事项:

1.如果出现 ERROR/AndroidRuntime(12705): java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation.一般是因为存在重复的类文件导致的,因为一般主程序直接引用jar包,系统会自动导出该依赖包,所以可以检查插件apk中是否重复导出了PluginService.jar

2.如果运行主程序出现找不到接口,可以查看是否正确导入依赖包PluginService.jar

差不多就是这个样子了,


© 著作权归作者所有

共有 人打赏支持
Kerison
粉丝 1
博文 28
码字总数 13985
作品 0
南京
netbeans搭建安卓开发环境

NetBeans 上开发 Android 应用程序需要安装一个 Android SDK 和针对 NetBeans 的 Android 开发插件 下载并安装 Android SDK 下载 Android SDK 解压后运行 toolsandroid.bat update sdk 进行升...

daniel-john
2014/06/29
0
2
Android插件化开发,初入殿堂

好久没有写博客了,这次准备写写我这几天的研究成果——Android插件化开发框架CJFrameForAndroid。 背景交代 首先,你需要知道什么是插件化开发。就拿最常见的QQ来说,在第三个界面动态那里有...

kymjs张涛
2014/10/12
0
9
apkplug主题切换功能之主题包打包编译-07

主题包与普通插件开发相同,只是须上传服务器进行编译生成apk主题包 一 主题包(插件)搭建 1.按照普通app创建流程创建安卓工程 2.按照apkplug插件开发流程添加必要文件 <apkplug插件开发> osg...

梁大帅
2014/05/26
0
0
Android开发工具Android Studio、Android SDK和Genymotion完全配置

所谓“工欲善其事,必先利其器”。Android Studio 是谷歌推出一个Android集成开发工具,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试...

游走于代码之间
08/17
0
0
Andrid SDK tools 目录下的工具介绍

Andrid SDK tools 目录下的工具介绍 Android SDK包含了各种各样的定制工具,简介如下: Android模拟器(Android Emulator ) 它是在你的计算机上运行的一个虚拟移动设备。你可以使用模拟器来...

流云的博客
2015/02/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ehlib 修改 使行号字体颜色 与标题字体颜色 一致

对ehlib 显示效果不够满意,而做的调整 修改这个过程:procedure TCustomDBGridEh.DrawIndicatorCell(ACol, ARow: Longint; AreaCol, AreaRow: Longint; ARect: TRect; AState: TGri......

vga
20分钟前
0
0
Bash重定向详解

Bash重定向详解 Bash的重定向指的是将命令的输入和输出导向不同地方,而不是默认的标准输入、标准输出和标准错误。Bash的重定向实际上是对标准输入、标准输出和标准错误的重置,进而将所需输...

小陶小陶
今天
3
0
EventBus原理深度解析

一、问题描述 在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用EventBus。由于Event...

yangjianzhou
今天
16
0
OpenCV图像处理实例:libuv+cvui显示摄像头视频

#include <iostream>#include <opencv2/opencv.hpp>#define CVUI_IMPLEMENTATION#include <cvui.h>extern "C"{#include <uv.h>}using namespace std;#define WINDOW_NAM......

IOTService
今天
3
0
openJDK之JDK9的String

1.openJDK8的String 先来看下openJDK8的String的底层,如下图1.1所示: 图1.1 底层上使用的是char[],即char数组 每个char占16个bit,Character.SIZE的值是16。 2.openJDK9中的String 图2.1...

克虏伯
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部