相关文章:
1、《插件化框架 RePlugin 应用之一:配置及内置插件》
2、《插件化框架 RePlugin 应用之二:内置插件的升级、卸载》
3、《插件化框架 RePlugin 应用之三:外置插件》
说干就干!
1、无论安装还是升级,都会将“源文件”“移动”(而非复制)到插件的安装路径(如app_p_a)上,这样可大幅度节省安装和升级时间,但显然的,“源文件”也就会消失
2、如果插件正在运行,则不会立即升级,而是“缓存”起来。直到所有“正在使用插件”的进程结束并重启后才会生效,升级可能会占用“内部存储空间”(因为要释放新的APK)
3、内置插件的升级分为两种情况:主程序随包升级、通过install方法升级
4、值得注意的是,无论采用何种方式,均“不支持降级”,但支持“同版本覆盖”升级,也即:
插件的升级版本就在原先已配置好【配置方法】,并已应用的插件项目中按正常项目开发升级即可:
其中,官网说“内置插件:只要APK的时间戳和大小发生变化就升级,若两者均无变化,则不会升级。”但是官网有《插件的信息》说明文档,里面用到了插件版本号这一设定,能规范化开发,所以建议采用:
然后打包,并把新包按之前的插件名修改:插件名.apk
修改完成后,放到自己服务器上,以供下载升级。【我这里用github】
在加入内置插件时如果有升级需求,那么之前就得有升级的逻辑代码,这里模拟插件升级,就简单地模拟把服务器中的已升级插件下载到手机,不做版本号检测什么的,下载API就直接用HttpURLConnection,模拟出效果即可,下载逻辑代码网上一大堆:
ps:如果用到6.0及以上的测试机,要动态申请读写权限。
public class UpdateService extends IntentService {
// 插件下载地址
String urlPath = "https://raw.githubusercontent.com/ZhangZeQiao/ImagePluginDemo/7c5866db83b57c455302fac12ea72af30d9a5364/app/src/main/assets/image.apk";
// 插件下载后的存放路径
String downloadDir = Environment.getExternalStorageDirectory().getAbsolutePath();
public UpdateService() {
// 实现父类的构造方法,用于命名工作线程,只用于调试。
super("UpdateService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务
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", "更新完成");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
直接安装已下载到手机的安装包:
RePlugin.install("/***/***/image.apk");
PluginInfo pi = RePlugin.install("/***/***/image.apk");
if (pi != null) {
RePlugin.preload(pi);
}
ps:demo时,原以为按后退键再进入就ok,但是此时还没回收,得完全退出程序后,再次进入才能升级插件。
如果插件正在运行,则不会立即卸载插件,而是将卸载诉求记录下来。直到所有“正在使用插件”的进程结束并重启后才会生效。
但是卸载只针对外置插件,由于内置插件是捆在主程序包内的,故无法卸载“内置插件”(此处有优化空间,官方还在商量对策)。
我们只能用删除的方式来“卸载”内置插件: 删除内置插件非常简单,直接移除相应的Jar文件,其余均交给RePlugin来自动化完成。
demo的github地址:
https://github.com/ZhangZeQiao/RePluginUseDemo.git
https://github.com/ZhangZeQiao/ImagePluginDemo.git