目录
Android 插件化,qihoo360插件方案
宿主App插件化: 插件App插件配置: 宿主调用插件App:
新建一个项目,开始配置
classpath 'com.qihoo360.replugin:replugin-host-gradle:2.2.4'
apply plugin: 'replugin-host-gradle'
其中repluginHostConfig 要看你是否使用AppCompat 来进行个性化配置
repluginHostConfig { /** * 是否使用 AppCompat 库 * 不需要个性化配置时,无需添加 */ useAppCompat = true }
compile 'com.qihoo360.replugin:replugin-host-lib:2.2.4'
让工程的 Application 直接继承自 RePluginApplication。
如果您的工程已有Application类,则可以将基类切换到RePluginApplication即可。或者您也可以用“非继承式”接入。
public class MainApplication extends RePluginApplication { }
若您的应用对Application类继承关系的修改有限制,或想自定义RePlugin加载过程(慎用!),则可以直接调用相关方法来使用RePlugin。
public class MainApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); RePlugin.App.attachBaseContext(this); .... } @Override public void onCreate() { super.onCreate(); RePlugin.App.onCreate(); .... } @Override public void onLowMemory() { super.onLowMemory(); /* Not need to be called if your application's minSdkVersion > = 14 */ RePlugin.App.onLowMemory(); .... } @Override public void onTrimMemory(int level) { super.onTrimMemory(level); /* Not need to be called if your application's minSdkVersion > = 14 */ RePlugin.App.onTrimMemory(level); .... } @Override public void onConfigurationChanged(Configuration config) { super.onConfigurationChanged(config); /* Not need to be called if your application's minSdkVersion > = 14 */ RePlugin.App.onConfigurationChanged(config); .... } }
classpath 'com.qihoo360.replugin:replugin-plugin-gradle:2.2.4'
apply plugin: 'replugin-plugin-gradle'
compile 'com.qihoo360.replugin:replugin-plugin-lib:2.2.4'
/*插件名配置*/ repluginPluginConfig { //插件名 pluginName = "androidgo" //宿主app的包名 hostApplicationId = "com.newdicooker.tempetek.hostreplugin" //宿主app的启动activity hostAppLauncherActivity = "com.newdicooker.tempetek.hostreplugin.MainActivity" }
以上步骤完后才能就是见证奇迹的时刻了:
调用内置插件 调用外置插件
插件App生成apk,将APK改名为:[插件名].jar 将[插件名].jar放入主程序的Assets/plugins目录下 可通过别名:”
RePlugin.startActivity(MainActivity.this, RePlugin.createIntent("androidgo", "com.newdicooker.tempetek.androidgo.MainActivity"));
androidgo:是插件App的别名
com.newdicooker.tempetek.androidgo.MainActivity:要启动App的启动页
可通过包名来进行访问:
RePlugin.startActivity(MainActivity.this, RePlugin.createIntent("com.newdicooker.tempetek.androidgo", "com.newdicooker.tempetek.androidgo.MainActivity"));
通过开启服务来进行异步下载任务的:
RePlugin.isPluginInstalled("image")是通过别名来判断插件是否安装,如果未安装则下载安装,如果已经安装则直接进入。
public void jumpToOut(View view) { if (RePlugin.isPluginInstalled("image")) { RePlugin.startActivity(MainActivity.this, RePlugin.createIntent("image", "com.xq.imageplugindemo.MainActivity")); return; } // 插件下载地址 String urlPath = "https://raw.githubusercontent.com/ZhangZeQiao/ImagePluginDemo/7c5866db83b57c455302fac12ea72af30d9a5364/app/src/main/assets/image.apk"; // 插件下载后的存放路径 String downloadDir = Environment.getExternalStorageDirectory().getAbsolutePath(); Intent intent = new Intent(this, DownloadAndUpdateService.class); intent.putExtra("urlPath", urlPath); intent.putExtra("downloadDir", downloadDir); startService(intent); }
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(); // http的连接类 HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection; // 设定请求的方法,默认是GET httpURLConnection.setRequestMethod("GET"); // 设置字符编码 httpURLConnection.setRequestProperty("Charset", "UTF-8"); // 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。 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 { } } }