android MDE工程师,Android Application Addon(插件) 架构及管理
一,原理(以浏览器为例)
本质:
1, 主程序直接加载插件的Extension类(这样他们就在同一个进程里了,就相当于主程序和Extension合为一个新的大app),通过接口来交互。
2, 插件Extension需要实现接口IExt
接口包括(部分):/* for browser activity */
public void onBrowserCreate(Bundle bundle);
public void onBrowserResume();
public void onBrowserPause();
public void onBrowserDestory();
3, 主程序需要实现IBrowserActivity接口
接口包括(部分):public boolean showToast(String pkgname, String content);
public boolean showProgressDialog(String pkgname,
PopupProgressDialogParams params);
public void dismissProgressDialog(String pkgname);
public IPopupProgressDialog getProgressDialog(String pkgname);
public boolean showPopupDialog(String pkgname, PopupDialogParams params);
public void dismissPopupDialog(String pkgname);
4, 通过一个类BrowserActivityImpl来执行,它持有主程序的Context,保存各个插件的各种数据(每个插件的Extension)。设计上BrowserActivity是单例模式,且为弱引用。
架构的示意图如下:
流程示例:
1, 主程序的onCreate()方法如何传给Addon
1-1 在主程序Activity的onCreate中,获得BrowserActivityImpl的实例
调用实例的traverseCreateActivityCallback()方法
1-2 在BrowserActivityImpl对象持有每个插件的Extension 的实例。
在此,会调用Extension中的onCreate()方法。
BrowserActivityImpl
2, Addon如何让主程序显示PopupDialog
1-1 初始化
主程序启动,Addon Extension获得BrowserActivityImpl的对象mBrowserActivityImpl
1-2 调用
Addon中,mBrowserActivity调用方法:
mBrowserActivityImpl.showProgressDialog(PKGNAME, mLoadingParams);
二,要点
1, 插件Extension类的加载
比较2.3和4.1的源码,Classloader和PathClassloader之间有所不同。
所以分别处理。4.1中,PathClassloader可以直接加载class,2.3中,通过load一个错误的class name,让PassClassloader获得的mDex文件的数据,然后通过mdex文件,加载类,相关源码,不给出,请自行查看。给出实现代码供参考:public class ExtClassLoader extends ClassLoader {
private static Field dexField;
private DexFile[] mDexs;
private final ClassLoader mLoader;
private static boolean ICE_OR_ABOVE = Build.VERSION.SDK_INT >= 14;
static {
if(!ICE_OR_ABOVE){
Class classLoader = PathClassLoader.class;
try {
dexField = classLoader.getDeclaredField("mDexs");
dexField.setAccessible(true);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
public ExtClassLoader(Context base,PackageInfo pi, String extPkg,
ClassLoader mainClassLoader) {
super(mainClassLoader);
Context extContext = null;
try {
extContext = base.createPackageContext(
extPkg,
Context.CONTEXT_INCLUDE_CODE
| Context.CONTEXT_IGNORE_SECURITY);
} catch (NameNotFoundException e1) {
e1.printStackTrace();
}
if(ICE_OR_ABOVE){
String codePath = extContext.getPackageCodePath();
String dir = pi.applicationInfo.nativeLibraryDir;
mLoader = new PathClassLoader(codePath, dir, mainClassLoader);
}else{
mLoader = extContext.getClassLoader();
}
}
@Override
protected Class> loadClass(String className, boolean arg1)
throws ClassNotFoundException {
if(ICE_OR_ABOVE)
return super.loadClass(className, arg1);
Class> c = findLoadedClass(className);
if (c != null)
return c;
try {
c = getParent().loadClass(className);
if (c == null)
c = findClass(className);
} catch (ClassNotFoundException e) {
c = findClass(className);
}
return c;
}
@Override
protected Class> findClass(String className)
throws ClassNotFoundException {
if(mLoader == null)
return null;
if(ICE_OR_ABOVE)
return mLoader.loadClass(className);
Class> c = null;
if (mLoader instanceof PathClassLoader)
c = loadClassFromDexFile(className);
else
c = mLoader.loadClass(className);
return c;
}
private Class> loadClassFromDexFile(String className) {
DexFile[] dfs = getDexFiles();
if (dfs != null) {
for (int i = 0; i < dfs.length; i++) {
if (dfs[i] != null) {
Class> c = dfs[i].loadClass(className, this);
if (c != null)
return c;
}
}
}
return null;
}
private DexFile[] getDexFiles() {
if (mDexs != null)
return mDexs;
try {
mLoader.loadClass("all.money.go.my.home");
} catch (Exception e) {
e.printStackTrace();
Log.e(ExtMgrConstants.LOGTAG, "getDexFiles " + e.toString());
}
try {
mDexs = (DexFile[]) dexField.get(mLoader);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return mDexs;
}
}
2, 进程的处理
根据以上的说明,即Addon的Extension类与主程序属于同一进程。但是Addon的其他类,则不属于主程序进程。
2-1 两个进程之间切换,需要sync
2-2 如果使用SharedPreference,需要使用多进程的构造方法。
2-3 友盟统计,如果要单独统计为Addon的数据。需要从Extension单起一个service来统计,因为Extension在主程序的进程中,统计的数据会到主程序。
三:项目
插件是特定应用(例如浏览器)提供的开放api的实现。开发者主要关注的是功能, 交互和UI。当然,需要注意第二部分给出的要点。
我参与了两个插件的开发,中间隔了很长的时间,会觉得再次进入需要一些熟悉的时间。觉得可以优化的地方,就是给出开发步骤文档。一些记忆性质的code flow可以避免。开发效率可以提高。
android MDE工程师,Android Application Addon(插件) 架构及管理相关推荐
- 如何成为android开发工程师,android开发工程师薪资 如何成为一名合格的android开发工程师?...
行业薪酬的影响因素包括行业内.外部因素及员工个人的因素,同样,在IT行业中,要想了解android开发工程师的薪资待遇情况如何,我们也可以从这几个因素入手,加以了解.android开发工程师薪资,如何 ...
- android MDE工程师,JustModeling: An MDE Approach to Develop Android Business Applications
摘要: The continuous growth of the Android market has resulted in greater demand for applications and ...
- android MDE工程师,【MDE工作内容|工作职责|MDE做什么】-看准网
要求A Manage development, selection, implementation & optimization of secondary operations for mec ...
- android软件工程师/android中间件开发
Android平台及中间件工程师 职责描述: 1 设计,集成和优化验证基于Android平台以下软件运行库 Multimedia: Video Middleware (OpenMAX, GStream ...
- android camera工程师,Android从Camera中获取图片的两种方法
方法一: 此方法会由Camera直接产生照片回传给应用程序,但是返回的是压缩图片,显示不清晰 /** 启动Camera */ private void intentCamera(){ try { ...
- Android开发工程师vs运维工程师
关于我 目录 1.什么是运维工程师 2.什么是Android开发工程师 未完待续 1.什么是运维工程师 对于初创公司,运维工程师的工作可能需要从申请域名开始,购买/租用服务器,上架,调整网络设备的设置 ...
- android 类加载器 DexClassLoader的用法,以及引出的插件架构
1.android 类加载器(DexClassLoader的用法),调用其他apk的类中的方法: 方式一: 然后在Host中利用下面的方式调用 PackageManager pm = getPacka ...
- Android魔镜:方法耗时统计插件Mirror-基础篇
晓锋,曾在PPTV工作,饿了么资深Android工程师,专注于Android单元测试.架构设计.性能优化.以及最新技术分享,个人博客:michaelzhong. 注:本篇是<Android魔镜: ...
- Android Framework中的Application Framework层介绍
Android的四层架构相比大家都很清楚,老生常谈的说一下分别为: Linux2.6内核层,核心库层,应用框架层,应用层.我今天重点介绍一下应用框架层Framework. Framework层为我们开 ...
最新文章
- 小明分享|8ms平台下工程源码分析
- java math max_Java Math类静态double max(double d1,double d2)示例
- 在国外当程序员爽吗?
- JS打开新窗口的2种方式
- Oracle | oracle11g安装环境变量配置
- tp-link无线网卡linux下的驱动,Ubuntu14下安装无线网卡驱动(TP-LINK TL-WN823N)
- ldap 统一认证 java_LDAP统一用户认证
- Python批量检测域名是否被注册
- 哔哩哔哩2018校招前端笔试
- english_搭配
- [生存志] 第141节 秦魏风俗掌故
- sql substr oracle,Substr也可以使用索引吗?
- 解决了计算机处理汉字的问题,计算机处理汉字必须解决的三个问题分别是汉字...
- 最小公倍数和最大公约数的三种算法
- inter酷睿后缀含义
- 车辆识别号(VIN)验证
- USACO 2021 January Contest, BronzeProblem 3. Just Stalling题解
- Password Management: Hardcoded Password
- Java(SpringMVC03)(SSM整合1)
- 可信时间戳服务,如何确保电子数据法律效力?
热门文章
- 不愿意和别人打交道_一个人不愿意和同事打交道,大多是这3个原因,你了解吗...
- Tomcat使用过滤器实现页面的限制访问,登录才能访问受限页面
- DC-DC升压和降压电路电感参数选择详解
- Unity视频播放的脚本控制
- 在阿里云国内搭建一个纯净的 kubernetes 环境
- 基于多重继承与信息内容的知网词语相似度计算 - 论文及代码讲解
- Android新机系统要求,原神手机端最低配置要求
- PrimoCache2.2.0汉化程序与2.0.0的交叉使用
- IGRP和EIGRP为什么是距离矢量协议
- GPRS优点介绍及GPRS上网相关知识(转)