1:新建一个java工程(我比较懒我就直接新建Android工程了) 2:然后看看包路径。 我们敲入里面的代码:先是Iinterface.java
packagecom.demo.dex; /** * 对外接口 * * @author edsheng * */ publicinterfaceIinterface { publicvoidcall(); publicString getData(); }
然后是Iclass.java
packagecom.demo.dex; importandroid.content.Context; importandroid.widget.Toast; publicclassIClass implementsIinterface { privateContext context; publicIClass(Context context) { super(); this.context = context; } @Override publicvoidcall() { Toast.makeText(context,"call method",0).show(); } @Override publicString getData() { return"hello,i am from IClass"; } }
导出我们的jar文件我给他命名为test.jar,然后把java的class文件转换成android能识别的字节码吧。使用dx工具,可以在andorid的SKD目录下面搜索一下这个工具,以前的说在platform-tools这个目录下面但是我没有找到,相反我在build-tools里面的子目录里面找到了不同版本的dx工具,我随便找了一个版本的19.0.3然后把test.jar复制到这个目录下面, 在cmd命令里面敲入
dx --dex --output=testdex.jar test.jar
然后贴出FileUtil.java的代码
packagecom.demo.utile; importjava.io.File; importjava.io.FileOutputStream; importjava.io.InputStream; importandroid.content.Context; importandroid.os.Environment; publicclassFileUtile { publicstaticvoid CopyAssertJarToFile(Context context, String filename, String des) { try{ File file = newFile(Environment.getExternalStorageDirectory() .toString() + File.separator + des); if(file.exists()) { return; } InputStream inputStream = context.getAssets().open(filename); file.createNewFile(); FileOutputStream fileOutputStream = newFileOutputStream(file); bytebuffer[] = newbyte[1024]; intlen = 0; while((len = inputStream.read(buffer)) != 0) { fileOutputStream.write(buffer,0, len); } fileOutputStream.close(); fileOutputStream.close(); }catch(Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
这个类主要的作用就是把我们的jar相当于解压到一个目录下面。我这里是解压到外置设备上的其实这样做的安全性并不高,但是为了方便我就这样做了,建议是解压到包目录下面。记住别忘了给应用加权限!!!!!文件读写权限!!!! 最后我们来看看Activity里面的代码
packagecom.demo.activity; importjava.io.File; importjava.lang.reflect.Constructor; importjava.lang.reflect.Method; importandroid.app.Activity; importandroid.content.Context; importandroid.os.Bundle; importandroid.os.Environment; importcom.demo.utile.FileUtile; importdalvik.system.DexClassLoader; publicclassMainActivity extendsActivity { @Override protectedvoidonCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); FileUtile.CopyAssertJarToFile(this,"testdex.jar","testdex.jar"); File file = newFile(Environment.getExternalStorageDirectory() .toString() + File.separator + "testdex.jar"); finalFile optimizedDexOutputPath = getDir("temp", Context.MODE_PRIVATE); DexClassLoader classLoader = newDexClassLoader(file.getAbsolutePath(), optimizedDexOutputPath.getAbsolutePath(),null, getClassLoader()); try{ Class<!--?--> iclass = classLoader.loadClass("com.demo.dex.IClass"); Constructor<!--?--> istructor = iclass.getConstructor(Context.class); //利用反射原理去调用 Method method = iclass.getMethod("call",null); String data = (String) method.invoke(istructor.newInstance(this),null); System.out.println(data); }catch(Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
其实这样调用还有一点要注意的是我感觉这样做每次都要去调用反射,总给我感觉来说不太友好,那么这里我有给出了下面一种写法,这种写法最主要的地方是,要获得Iinterface这个接口,把Iinterface.java这个文件复制到你的工程里面,记得包名相同,调用的时候我们可以这样来调用它。
Class<!--?--> iclass = classLoader.loadClass("com.demo.dex.IClass"); Constructor<!--?--> istructor = iclass.getConstructor(Context.class); Iinterface iinterface = (Iinterface) istructor.newInstance(this); String data = iinterface.getData(); iinterface.call(); Toast.makeText(this, data, 0).show();