想实现一种可扩展插件的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