使用assets目录来实现插件机制
/** * 管理接口。 * @author jevan * @version 1.0 at 2013-12-6 * */ public interface IManage { /** * 注册平台接口。 * @param param 传入参数,可选。 */ public boolean regPlatform(String param); }
插件管理类:
/** * @author jevan * @version 1.0 at 2013-12-6 用于初始化平台信息 */ private static void initPlatformInstance(Context context) { String path = context.getFilesDir().getAbsolutePath() + "/jar/"; String[] files = null; File fpath = new File(path); if (!fpath.exists()) { fpath.mkdirs(); } try {// 遍历assest文件夹,读取压缩包及安装包 files = context.getAssets().list(""); } catch (IOException e) { e.printStackTrace(); } if (files == null) { return; } List<String> apkList = new ArrayList<String>(); // 动态绑定,运行实现了这个接口的类的方法 for (String fileName : files) { if (fileName.endsWith(".apk")) { Log.i("fileName", "src files: " + fileName); Log.i("fileName", "dst files: " + path + fileName); copy(context, fileName, path, fileName); apkList.add(path + fileName); } } getPlatformInstanceVerB(context, apkList, path); } /** * 统一平台的插件实现。 * * @param context * Context * @param apkList * 传入的apk文件列表。 */ public static void getPlatformInstanceVerB(Context context, List<String> apkList, String path) { for (String file : apkList) { Log.i("fileName", " fileName: " + file); File jarFile = new File(file); if (jarFile.exists()) { DexClassLoader cl = new DexClassLoader(jarFile.toString(), path, null, ClassLoader.getSystemClassLoader()); Class clazz = null; Object obj = null; try { clazz = cl.loadClass("com.ott.porting.PortingManage"); // 对这个类进行实例化 obj = clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // 如果有这个插件,就进行下面的动作,如果没有这个插件就返回 if (clazz == null) { return; } try { IManage manage = (IManage) obj; manage.regPlatform(null); } catch (Exception e) { e.printStackTrace(); } // 把Object转换成接口类型 if(obj instanceof IManage) { Log.i("fileName", " obj is IManage! "); IManage manage = (IManage) obj; manage.regPlatform(null); } else { Log.i("fileName", " obj is not IManage! "); } } } }
copy函数的实现:
1 /** 2 * 拷贝assets目录下的文件到 savePath 3 * 4 * @param myContext 5 * @param ASSETS_NAME 6 * 要复制的文件名 7 * @param savePath 8 * 要保存的路径 9 * @param saveName 10 * 复制后的文件名 testCopy(Context context)是一个测试例子。 11 */ 12 public static void copy(Context myContext, String ASSETS_NAME, 13 String savePath, String saveName) { 14 String filename = savePath + "/" + saveName; 15 16 File dir = new File(savePath); 17 // 如果目录不中存在,创建这个目录 18 if (!dir.exists()) 19 dir.mkdir(); 20 try { 21 if (!(new File(filename)).exists()) { 22 InputStream is = myContext.getResources().getAssets() 23 .open(ASSETS_NAME); 24 FileOutputStream fos = new FileOutputStream(filename); 25 byte[] buffer = new byte[2048]; 26 int count = 0; 27 while ((count = is.read(buffer)) > 0) { 28 fos.write(buffer, 0, count); 29 } 30 fos.close(); 31 is.close(); 32 } 33 } catch (Exception e) { 34 e.printStackTrace(); 35 } 36 }
有个异常:
1 Android java.lang.ClassCastException: cannot be cast to
抽时间找下解决方式。
2013-12-11更新:
1、解决Android java.lang.ClassCastException: cannot be cast to这个异常:
1 /** 2 * apk的插件另外一种实现。 3 * 4 * @param context 5 * Context 6 * @param apkList 7 * 传入的apk文件列表。 8 */ 9 public static void getPlatformInstanceVerB(Context context, 10 List<String> apkList, String path) { 11 for (String file : apkList) { 12 Log.i("fileName", " fileName: " + file); 13 File jarFile = new File(file); 14 if (jarFile.exists()) { 15 DexClassLoader cl = new DexClassLoader(jarFile.toString(), 16 path, null, ClassLoader.getSystemClassLoader()); 17 Class clazz = null; 18 Object instance = null; 19 try { 20 clazz = cl.loadClass("com.ott.porting.PortingManage"); 21 Constructor localConstructor = clazz.getConstructor(new Class[] {}); 22 23 instance = localConstructor.newInstance(new Object[] {}); 24 25 //无参数方法 26 //Method des = clazz.getMethod("regPlatform"); 27 //des.invoke(instance); 28 29 //有参数方法 30 Method methodRegPlatform = clazz.getDeclaredMethod("regPlatform", new Class[] { String.class }); 31 methodRegPlatform.setAccessible(true); 32 methodRegPlatform.invoke(instance, "test for jevan"); 33 // 对这个类进行实例化 34 //obj = clazz.newInstance(); 35 36 } catch (ClassNotFoundException e) { 37 e.printStackTrace(); 38 } catch (InstantiationException e) { 39 e.printStackTrace(); 40 } catch (IllegalAccessException e) { 41 e.printStackTrace(); 42 } catch (NoSuchMethodException e) { 43 e.printStackTrace(); 44 } catch (SecurityException e) { 45 e.printStackTrace(); 46 } catch (IllegalArgumentException e) { 47 e.printStackTrace(); 48 } catch (InvocationTargetException e) { 49 e.printStackTrace(); 50 } 51 // 如果有这个插件,就进行下面的动作,如果没有这个插件就返回 52 if (clazz == null) { 53 return; 54 } 55 56 57 // // 把Object转换成接口类型 58 // if (obj instanceof IManage) { 59 // Log.i("fileName", " obj is IManage! "); 60 // IManage manage = (IManage) obj; 61 // manage.regPlatform(null); 62 // } else { 63 // Log.i("fileName", " obj is not IManage! "); 64 // } 65 } 66 } 67 }