插件化框架 RePlugin 应用之三:外置插件
2017-08-15 22:11
696 查看
相关文章:
1、《插件化框架 RePlugin 应用之一:配置及内置插件》
2、《插件化框架 RePlugin 应用之二:内置插件的升级、卸载》
3、《插件化框架 RePlugin 应用之三:外置插件》
说干就干!
外置插件的操作跟内置插件差不多。
接入配置第 1 步:在作为插件的项目中添加 RePlugin Plugin Gradle 依赖
在项目根目录的 build.gradle(注意:不是 app/build.gradle) 中添加 replugin-plugin-gradle 依赖:
接入配置第 2 步:添加 RePlugin Plugin Library 依赖
在 app/build.gradle 中应用 replugin-plugin-gradle 插件,并添加 replugin-plugin-lib 依赖 :
最后:声明插件别名、插件版本号
若想改变这个行为,可以参考RePluginConfig中的 setMoveFileWhenInstalling() 方法
升级插件和此等同,故不再赘述
2、如果插件正在运行,则不会立即升级,而是“缓存”起来。直到所有“正在使用插件”的进程结束并重启后才会生效,升级可能会占用“内部存储空间”(因为要释放新的APK)
3、如果插件正在运行,则不会立即卸载插件,而是将卸载诉求记录下来。直到所有“正在使用插件”的进程结束并重启后才会生效
4、安装或升级失败(返回值为Null)的原因有如下几种:
是否开启了“签名校验”功能且签名不在“白名单”之中?——通常在Logcat中会出现“verifySignature: invalid cert: ”。如是,则请参考“安全与签名校验”一节,了解如何将签名加白,或关闭签名校验功能(默认为关闭)
是否将replugin-host-lib升级到2.1.4及以上?——在2.1.3及之前版本,若没有填写“meta-data”,则可能导致安装失败,返回值为null。我们在 2.1.4 版本中已经修复了此问题(卫士和其它App的所有插件都填写了meta-data,所以问题没出现)
APK安装包是否有问题?——请将“插件APK”直接安装到设备上(而非作为插件)试试。如果在设备中安装失败,则插件安装也一定是失败的。
是否没有SD卡的读写权限?——如果您的插件APK放到了SD卡上,则请务必确保主程序中拥有SD卡权限(主程序Manifest要声明,且ROM允许),否则会出现权限问题,当然,放入应用的files目录则不受影响。
设备内部存储空间是否不足?——通常出现此问题时其Logcat会出现“copyOrMoveApk: Copy/Move Failed”的警告。如是,则需要告知用户去清理手机。
5、值得注意的是,无论采用何种方式(内置/外置),均“不支持降级”,但支持“同版本覆盖”升级,也即:
内置插件:只要APK的时间戳和大小发生变化就升级,若两者均无变化,则不会升级。(在 RePlugin 2.1.5版本中开始支持)
外置插件:只要调用 RePlugin.install 方法即可将“内置插件”转化为“外置插件”。同样的,需遵循安装插件规则。
插件按平常项目开发流程进行开发,开发修改完成后,打包成apk放到自己服务器上,以供下载升级。【我这里用github】
2、安装和更新外置插件
安装和更新都是直接安装已下载到手机的安装包:
大部分情况下,应尽可能“静默升级”,以减少对用户的打扰
针对升级而言,可在后台线程做一次“预加载”,提前释放Dex。具体做法:
若插件没有运行,则可直接升级
若插件正在运行,则会有两种场景,需分别对待:
– 若是遇到严重问题,需要“强制升级”,则应立即提示用户,待同意后则重启进程
– 通常情况下,建议在“锁定屏幕”后重启进程,让其在后台生效
ps:demo时,原以为按后退键再进入就ok,但是此时还没回收,得完全退出程序后,再次进入才能升级插件。
3、卸载外置插件
要卸载插件,则需要使用 RePlugin.uninstall 方法。只需传递一个“插件名”即可:
注意:如果插件正在运行,则不会立即卸载插件,而是将卸载诉求记录下来。直到所有“正在使用插件”的进程结束并重启后才会生效。
demo的github地址:
https://github.com/ZhangZeQiao/RePluginUseDemo.git
https://github.com/ZhangZeQiao/ImagePluginDemo.git
1、《插件化框架 RePlugin 应用之一:配置及内置插件》
2、《插件化框架 RePlugin 应用之二:内置插件的升级、卸载》
3、《插件化框架 RePlugin 应用之三:外置插件》
说干就干!
外置插件的操作跟内置插件差不多。
一、插件项目的接入配置【地址】
无论是内置,还是外置插件,还需理解:不是所有的APK都能作为 RePlugin 的插件并安装进来的,必须要严格按照《插件接入指南》中所述完成接入,其编译出的APK才能成为插件,且这个APK同时也可以被安装到设备中。接入配置第 1 步:在作为插件的项目中添加 RePlugin Plugin Gradle 依赖
在项目根目录的 build.gradle(注意:不是 app/build.gradle) 中添加 replugin-plugin-gradle 依赖:
buildscript { dependencies { classpath 'com.qihoo360.replugin:replugin-plugin-gradle:2.1.7' ... } }
接入配置第 2 步:添加 RePlugin Plugin Library 依赖
在 app/build.gradle 中应用 replugin-plugin-gradle 插件,并添加 replugin-plugin-lib 依赖 :
apply plugin: 'replugin-plugin-gradle' dependencies { compile 'com.qihoo360.replugin:replugin-plugin-lib:2.1.7' ... }
最后:声明插件别名、插件版本号
<!--要声明插件别名,需要在插件的AndroidManifest.xml中声明以下Meta-data:--> <!--查看奇虎360的 RePlugin/replugin-sample/--> <meta-data android:name="com.qihoo360.plugin.name" android:value="text"/> <!--插件版本号--> <meta-data android:name="com.qihoo360.plugin.version.ver" android:value="100"/>
二、注意事项【地址】
1、无论安装还是升级,都会将“源文件”“移动”(而非复制)到插件的安装路径(如app_p_a)上,这样可大幅度节省安装和升级时间,但显然的,“源文件”也就会消失若想改变这个行为,可以参考RePluginConfig中的 setMoveFileWhenInstalling() 方法
升级插件和此等同,故不再赘述
2、如果插件正在运行,则不会立即升级,而是“缓存”起来。直到所有“正在使用插件”的进程结束并重启后才会生效,升级可能会占用“内部存储空间”(因为要释放新的APK)
3、如果插件正在运行,则不会立即卸载插件,而是将卸载诉求记录下来。直到所有“正在使用插件”的进程结束并重启后才会生效
4、安装或升级失败(返回值为Null)的原因有如下几种:
是否开启了“签名校验”功能且签名不在“白名单”之中?——通常在Logcat中会出现“verifySignature: invalid cert: ”。如是,则请参考“安全与签名校验”一节,了解如何将签名加白,或关闭签名校验功能(默认为关闭)
是否将replugin-host-lib升级到2.1.4及以上?——在2.1.3及之前版本,若没有填写“meta-data”,则可能导致安装失败,返回值为null。我们在 2.1.4 版本中已经修复了此问题(卫士和其它App的所有插件都填写了meta-data,所以问题没出现)
APK安装包是否有问题?——请将“插件APK”直接安装到设备上(而非作为插件)试试。如果在设备中安装失败,则插件安装也一定是失败的。
是否没有SD卡的读写权限?——如果您的插件APK放到了SD卡上,则请务必确保主程序中拥有SD卡权限(主程序Manifest要声明,且ROM允许),否则会出现权限问题,当然,放入应用的files目录则不受影响。
设备内部存储空间是否不足?——通常出现此问题时其Logcat会出现“copyOrMoveApk: Copy/Move Failed”的警告。如是,则需要告知用户去清理手机。
5、值得注意的是,无论采用何种方式(内置/外置),均“不支持降级”,但支持“同版本覆盖”升级,也即:
内置插件:只要APK的时间戳和大小发生变化就升级,若两者均无变化,则不会升级。(在 RePlugin 2.1.5版本中开始支持)
外置插件:只要调用 RePlugin.install 方法即可将“内置插件”转化为“外置插件”。同样的,需遵循安装插件规则。
三、外置插件的安装、更新、卸载
1、修改下载Service代码逻辑public class DownloadAndUpdateService extends IntentService { public DownloadAndUpdateService() { // 实现父类的构造方法,用于命名工作线程,只用于调试。 super("DownloadAndUpdateService"); } @Override protected void onHandleIntent(@Nullable Intent intent) { // Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务 // 插件下载地址 String urlPath = intent.getStringExtra("urlPath"); // 插件下载后的存放路径 String downloadDir = intent.getStringExtra("downloadDir"); File file = null; try { URL url = new URL(urlPath); URLConnection urlConnection = url.openConnection(); HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection; httpURLConnection.setRequestMethod("GET"); httpURLConnection.setRequestProperty("Charset", "UTF-8"); httpURLConnection.connect(); int fileLength = httpURLConnection.getContentLength(); String filePathUrl = httpURLConnection.getURL().getFile(); String fileFullName = filePathUrl.substring(filePathUrl.lastIndexOf(File.separatorChar) + 1); URLConnection con = url.openConnection(); BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream()); String path = downloadDir + File.separatorChar + fileFullName; file = new File(path); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } OutputStream out = new FileOutputStream(file); int size = 0; int len = 0; byte[] buf = new byte[1024]; while ((size = bin.read(buf)) != -1) { len += size; out.write(buf, 0, size); // 下载百分比 Log.v("xq", "下载了-------> " + len * 100 / fileLength); } bin.close(); out.close(); // 升级安装插件新版本 RePlugin.install(path); Log.v("xq", "下载完成 : " + path); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { } } }
插件按平常项目开发流程进行开发,开发修改完成后,打包成apk放到自己服务器上,以供下载升级。【我这里用github】
2、安装和更新外置插件
安装和更新都是直接安装已下载到手机的安装包:
RePlugin.install("/***/***/text.apk");
大部分情况下,应尽可能“静默升级”,以减少对用户的打扰
针对升级而言,可在后台线程做一次“预加载”,提前释放Dex。具体做法:
PluginInfo pi = RePlugin.install("/***/***/text.apk"); if (pi != null) { RePlugin.preload(pi); }
若插件没有运行,则可直接升级
若插件正在运行,则会有两种场景,需分别对待:
– 若是遇到严重问题,需要“强制升级”,则应立即提示用户,待同意后则重启进程
– 通常情况下,建议在“锁定屏幕”后重启进程,让其在后台生效
ps:demo时,原以为按后退键再进入就ok,但是此时还没回收,得完全退出程序后,再次进入才能升级插件。
3、卸载外置插件
要卸载插件,则需要使用 RePlugin.uninstall 方法。只需传递一个“插件名”即可:
RePlugin.uninstall("text");
注意:如果插件正在运行,则不会立即卸载插件,而是将卸载诉求记录下来。直到所有“正在使用插件”的进程结束并重启后才会生效。
demo的github地址:
https://github.com/ZhangZeQiao/RePluginUseDemo.git
https://github.com/ZhangZeQiao/ImagePluginDemo.git
相关文章推荐
- 插件化框架 RePlugin 应用之二:内置插件的升级、卸载
- 插件化框架 RePlugin 应用之一:配置及内置插件
- Replugin插件化技术解读之框架初始化、插件安装与加载(一)
- Android 插件化框架 RePlugin 使用技巧避免插件中使用.so产生的冲突
- 360插件化方案RePlugin学习笔记-外置插件
- Replugin插件化技术解读之框架初始化、插件安装与加载(二)
- Winform开发框架之插件化应用框架实现
- 基于插件技术的GIS应用框架(C# + ArcEngine9.3)(十二)
- Application应用框架思考(三) 之[插件机制]
- 应用开发框架之——插件、包
- 分页查询插件在框架中的应用
- 360开源的插件化框架Replugin深度剖析
- Android插件化框架 RePlugin 初探
- 基于插件技术的GIS应用框架(C# + ArcEngine9.3)(一)
- 基于插件技术的GIS应用框架(C# + ArcEngine9.3)(一)
- WCF开发框架之插件化应用模式升级
- Android Small插件化框架--启动插件Activity源码解析(下)
- android插件化框架-Replugin
- 基于插件技术的GIS应用框架(C# + ArcEngine9.3)(二)
- 基于插件技术的GIS应用框架(C# + ArcEngine9.3)(一)