/**
* 管理接口。
* @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函数的实现:

     /**
* 拷贝assets目录下的文件到 savePath
*
* @param myContext
* @param ASSETS_NAME
* 要复制的文件名
* @param savePath
* 要保存的路径
* @param saveName
* 复制后的文件名 testCopy(Context context)是一个测试例子。
*/
public static void copy(Context myContext, String ASSETS_NAME,
String savePath, String saveName) {
String filename = savePath + "/" + saveName; File dir = new File(savePath);
// 如果目录不中存在,创建这个目录
if (!dir.exists())
dir.mkdir();
try {
if (!(new File(filename)).exists()) {
InputStream is = myContext.getResources().getAssets()
.open(ASSETS_NAME);
FileOutputStream fos = new FileOutputStream(filename);
byte[] buffer = new byte[2048];
int count = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer, 0, count);
}
fos.close();
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}

有个异常:

 Android java.lang.ClassCastException: cannot be cast to

抽时间找下解决方式。

2013-12-11更新:

1、解决Android java.lang.ClassCastException: cannot be cast to这个异常:

     /**
* apk的插件另外一种实现。
*
* @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 instance = null;
try {
clazz = cl.loadClass("com.ott.porting.PortingManage");
Constructor localConstructor = clazz.getConstructor(new Class[] {}); instance = localConstructor.newInstance(new Object[] {}); //无参数方法
//Method des = clazz.getMethod("regPlatform");
//des.invoke(instance); //有参数方法
Method methodRegPlatform = clazz.getDeclaredMethod("regPlatform", new Class[] { String.class });
methodRegPlatform.setAccessible(true);
methodRegPlatform.invoke(instance, "test for jevan");
// 对这个类进行实例化
//obj = clazz.newInstance(); } catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// 如果有这个插件,就进行下面的动作,如果没有这个插件就返回
if (clazz == null) {
return;
} // // 把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! ");
// }
}
}
}

使用assets目录来实现插件机制的更多相关文章

  1. 探寻 webpack 插件机制

    webpack 可谓是让人欣喜又让人忧,功能强大但需要一定的学习成本.在探寻 webpack 插件机制前,首先需要了解一件有意思的事情,webpack 插件机制是整个 webpack 工具的骨架,而 ...

  2. android studio 使用gradle 导出jar包,并打包assets目录

    警告:本文年久失修. 随着android studio的升级 ,gradle的升级,严格按照本文的代码去做可能不会成功,希望依然可以作为解决问题的思路. 最近项目在做一个sdk,供别的开发者使用,所以 ...

  3. ImitateLogin新增插件机制以及又一个社交网站的支持

    我的文章里已经多次介绍 imitate-login ,这是我最近一直在维护的一个使用c#模拟社交网站登录的开源项目,现在新增了对插件的支持以及一个新的网站(由于某种原因,会在文章结束部分介绍:而且仅会 ...

  4. Maven生命周期和插件机制

    Maven中的一个非常重要的概念是生命周期和插件,这篇文章重点介绍下Maven的生命周期. Maven的生命周期是抽象的,具体的功能是有具体的插件来完成的,Maven有相当多的功能插件,以至于Mave ...

  5. php中的钩子(hook插件机制)

    对"钩子"这个概念其实不熟悉,最近看到一个php框架中用到这种机制来扩展项目,所以大概来了解下. hook插件机制的基本思想: 在项目代码中,你认为要扩展(暂时不扩展)的地方放置一 ...

  6. typecho流程原理和插件机制浅析(第一弹)

    typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...

  7. [转]--android studio 使用gradle 导出jar包,并打包assets目录

    转自: http://www.cnblogs.com/wuya/p/android-studio-gradle-export-jar-assets.html   最近项目在做一个sdk,供别的开发者使 ...

  8. NopCommerce架构分析之四----插件机制

    NopCommerce支持灵活的插件机制,所谓Web系统插件,其实也就是可以像原系统的一部分一样使用. Web系统的使用方式就是客户端发送一个请求,服务端进行解析.在asp.net MVC中对客户请求 ...

  9. php插件机制实现原理

    插件,亦即Plug-in,是指一类特定的功能模块(通常由第三方开发者实现) 它的特点: 1. 随时安装.卸载.激活.禁用 2. 无论什么状态都不影响系统核心模块的运行, 3. 是一种非侵入式的模块化设 ...

随机推荐

  1. BZOJ 3299: [USACO2011 Open]Corn Maze玉米迷宫(BFS)

    水题一道却交了4次QAQ,真是蒟蒻QAQ CODE: #include<cstdio>#include<iostream>#include<cstring>#inc ...

  2. [Kafka] - Kafka基本操作命令

    Kafka支持的基本命令位于${KAFKA_HOME}/bin文件夹中,主要是kafka-topics.sh命令:Kafka命令参考页面: kafka-0.8.x-帮助文档  -1. 查看帮助信息 b ...

  3. 【转】Nutch的Hadoop方式爬取效率优化

    原文地址:http://my.oschina.net/junfrank/blog/290404

  4. shell 获取指定目录下文件名

    有两个目录a.b,两个文件夹目录里有一些文件的文件名是一样,不过后缀名不同,我想把a文件夹下跟b文件夹里相同文件名的文件覆盖到b去,并删除b里同名而不同后缀的文件,文件很多    #!/bin/bas ...

  5. Ghostscript.Net Pdf 转 Image

    需求: 项目中需要实现PPT转Image的功能,之前项目中用的是使用Office COM组件实现的功能,通过.NET与Office COM组件的互操作(Interop)来操作Office文档 但是在生 ...

  6. 向上管理(manage up)的的五条原则

    绝大多数的工程师很可能很少关注代码之外的能力,摸爬滚打了将近10年后,我才领悟到除了技术之外还有一项最重要的修炼,那就是"领导与被领导"学(其中包含了换位思考,但不局限于换位思考) ...

  7. observe.js 源码 学习笔记

    /** * observejs --- By dnt http://kmdjs.github.io/ * Github: https://github.com/kmdjs/observejs * MI ...

  8. 数据库 t-sql 语句

    sql 高级语句  在基础语句上加上条件 条件修改: update 表名set 列明=要修改的值  where 列名 =原来的值 条件删除    删除  这个值的的一行 delete from 表名 ...

  9. Sersync实时同步

    sersync会对目录进行监控,将变化的目录或文件同步到远程服务器.sersync是递归监控的,如果有多级目录 ,都会同步到远程服务器. sersync依赖于rsync进行同步,在同步主服务器上开启s ...

  10. 1613: [Usaco2007 Jan]Running贝茜的晨练计划

    1613: [Usaco2007 Jan]Running贝茜的晨练计划 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1252  Solved: 609 ...