Android用DexClassLoader实现动态调用jar包

想实现一种可扩展插件的Android程序。Android项目中有一些预留的接口,功能代码从网络获取的jar包提取。


1、首先创建一个Android项目,用于导出jar包

(1)、建立一个MainInterface的类,用于给Android项目的接口。

package com.interfaces;

public interface MainInterface {
	public String sayHello();
}
(2)、建立一个InterfaceTest类实现MainInterface类

package com.interfaces;

public class InterfaceTest implements MainInterface {

	@Override
	public String sayHello() {
		return "hello world";
	}
}

(3)、导出jar包

导出时可以不勾选那些无用的文件,而且不能导出声明接口的类。

(4)、获取dex文件

Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行。

dx --dex --output=output.jar input.jar
此dx在Android sdk的platform-tools下。


2、创建一个Android测试项目

(1)、主的activity:

package com.dexandroidtest;

import java.io.File;

import com.interfaces.MainInterface;

import dalvik.system.DexClassLoader;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		test(getApplicationContext());
	}

	private void test(Context context) {
		try {
			File sourceFile = new File(
					Environment.getExternalStorageDirectory() + File.separator
							+ "dextest.jar");// 导出的jar的存储位置
			File file = context.getDir("osdk", 0);// dex临时存储路径
			DexClassLoader classLoader = new DexClassLoader(
					sourceFile.getAbsolutePath(), file.getAbsolutePath(), null,
					context.getClassLoader());

			Class<?> libProviderClazz = classLoader
					.loadClass("com.interfaces.InterfaceTest");

			MainInterface mMainInterface = (MainInterface) libProviderClazz
					.newInstance();// 接口
			String str = mMainInterface.sayHello();// 获取jar包提供的数据
			Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}

这样就可以实现动态加载了。

注1:此方法是无法加载activity、service等Android特有的累,就算是在Android项目的AndroidManifest中定义也没用。有个方法就是Android项目中定义好空的service,然后再service中调用接口实现功能。

注2:参考

http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html

http://my.oschina.net/Jerryking/blog/111575

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值