-
Notifications
You must be signed in to change notification settings - Fork 43
android 插件化开发研究
cheyiliu edited this page Apr 8, 2015
·
1 revision
- 百度云推送 遇到了一个困惑,他里面用到了plugin的思路来部署jar
- 之前在网络上看到一些关于android插件开发的帖子,但自己没深入研究,借此机会深入理解下
- (访问资源getResourcesForApplication(packageName),若不安装则无法获取资源? no, 见这个框架https://github.com/cheyiliu/dynamic-load-apk)
- 使用“插件”模式定制皮肤1 http://www.longdw.com/plugin-skin/
- 使用“插件”模式定制皮肤2 http://www.longdw.com/plugin-skin-2/
- activity增加internt-filter的action,同时插件里的activity的所有activity去掉默认的
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
这样插件apk在all app list中不可见。
<activity
android:name="com.xx.xxxxx.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="com.xx.xx.plugin"/>
</intent-filter>
</activity>
- 通过PackageManager发现插件
Intent intent = new Intent("com.xx.xx.plugin", null);
pm = getPackageManager();
pm.queryIntentActivities(intent, 0);
- 定义接口 (注意,在host工程里定义)
public interface IPlugin {
public void setContext(Context context);
public String getString(String packageName);
public Drawable getDrawable(String name, String packageName);
}
- 导出接口文件到jar, 右键host->export->java, jar file->select only the interface file, mark "export generated class files and resources"->next ... done
- 插件工程依赖于导出的接口jar, 实践证明,这个jar只能是通过插件工程的"java build path"方式导入,而不能放到libs目录下
- 插件要实现发现机制, 见上面
- 实现IPlugin接口
- 例子见demo
- 发现, 见上文
- 加载, DexClassLoader loadClass()
private IPlugin getPlugin(ResolveInfo rinfo) {
ActivityInfo ainfo = rinfo.activityInfo;
String packageName = ainfo.packageName;
String dexPath = ainfo.applicationInfo.sourceDir;
String dexOutputDir = getApplicationInfo().dataDir;
String libPath = ainfo.applicationInfo.nativeLibraryDir;
DexClassLoader cl = new DexClassLoader(dexPath, dexOutputDir, libPath,
this.getClass().getClassLoader());
try {
Class<?> clazz = cl.loadClass(packageName + ".SelectSkin");//hard code the interface impl name, not so good!
IPlugin plugin = (IPlugin) clazz.newInstance();
plugin.setContext(this);
return plugin;
} catch (Exception e) {
}
return null;
}
- 使用
plugin.getDrawable("icon", info.activityInfo.packageName);
- TODO (和上面需要访问资源的例子类似)
- apkplug http://www.apkplug.com/
- apkplug的博客 http://blog.csdn.net/o1587790525?viewmode=contents
- https://github.com/umeng/apf
- https://github.com/cheyiliu/dynamic-load-apk
- https://github.com/cheyiliu/android-plugin
- https://github.com/cheyiliu/CJFrameForAndroid
- https://github.com/cheyiliu/AndroidDynamicLoader
- key, DexClassLoader
- 反射
- http://my.oschina.net/u/2289564/blog/393252
- https://github.com/mmin18/AndroidDynamicLoader
- http://blog.csdn.net/bboyfeiyu/article/details/11597051
- http://blog.csdn.net/singwhatiwanna/article/details/22597587
- http://blog.csdn.net/bboyfeiyu/article/details/11710497
- http://www.longdw.com/plugin-skin-2/ http://www.longdw.com/plugin-skin/
- https://github.com/cheyiliu/dynamic-load-demo
Just build something.