目錄
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 { } } }