使用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     }
原文地址:https://www.cnblogs.com/jevan/p/3467525.html