[Android 插件化(二)] DroidPlugin 用法
1 簡(jiǎn)介
關(guān)于Android插件化可以查看我的前一篇博客:?
[Android 插件化(一)] DynamicLoadApk的用法
本篇介紹第二種實(shí)現(xiàn)插件化的框架,360公司出品的DroidPlugin框架,個(gè)人比較推薦使用這個(gè)框架來(lái)實(shí)現(xiàn)插件化,畢竟是大廠出的東西,已經(jīng)在360手機(jī)助手上用上了,可以放心使用,如果有坑的話,360會(huì)去填的嘛
DroidPlugin的Github地址:https://github.com/Qihoo360/DroidPlugin
DroidPlugin的優(yōu)點(diǎn):
- 宿主和插件完全隔離,插件不依賴宿主,可以獨(dú)立安裝運(yùn)行
- 低入侵設(shè)計(jì),插件不需要繼承任何類,和正常的app是一樣的。相比于Dynamic-load-apk框架插件需要繼承指定類,DroidPlugin的插件開發(fā)無(wú)門檻,更友好
- 宿主程序集成DroidPlugin框架簡(jiǎn)單
- 支持四大組件,完全使用Android的API。Dynamic-load-apk即使在插件中也要使用指定的api來(lái)啟動(dòng)Activity
DroidPlugin的缺點(diǎn):
暫時(shí)沒(méi)有發(fā)現(xiàn)什么大的缺點(diǎn),小的缺點(diǎn)就是插件啟動(dòng)速度太慢,還有就是宿主只能調(diào)用插件為L(zhǎng)auncher的Activity,宿主不能和插件中其他Activity交互,也就是說(shuō)插件是個(gè)單獨(dú)的模塊,只有單一入口。?
如果你發(fā)現(xiàn)其他缺點(diǎn),歡迎給我留言
同樣,本篇博客不講實(shí)現(xiàn)原理,只講怎樣使用,怎樣快速集成到自己的項(xiàng)目中
2 創(chuàng)建工程
(1) 下載DroidPlugin到本地,解壓后如下圖:
(2) 創(chuàng)建一個(gè)測(cè)試工程DroidPluginTest,新建兩個(gè)模塊:host,plugin。分別是宿主工程和插件工程,這兩個(gè)模塊都是application,最后都要生成apk。導(dǎo)入project\Libraries下面的庫(kù)DroidPlugin到新建的工程中,導(dǎo)入方法是:?
new–>import module–>選擇路徑: DroidPlugin-master\project\Libraries\DroidPlugin。?
目錄結(jié)構(gòu)如下圖:
工程目錄創(chuàng)建完畢
3 集成DroidPlugin框架
(1) 修改DroidPlugin的AndroidManifest.xml將所有的provider對(duì)應(yīng)的authorities修改成自己的,默認(rèn)為com.morgoo.droidplugin_stub_P00,可以修改為自己的包名,如: com.example.droidplugin_stub_P00 防止跟其它本插件使用者沖突。本例中修改為:com.host.droidplugin_stub_P00,如下圖:
注意:只修改前面的com.morgoo.droidplugin部分,后面的P00,P01…..不要改。?
如果不改authorities的話,會(huì)和360手機(jī)助手發(fā)生沖突,手機(jī)上裝了360手機(jī)助手,再裝這個(gè)就裝不上去了
(2) 修改PluginManager.STUB_AUTHORITY_NAME 為你的值,本例修改如下:
PluginManager.STUB_AUTHORITY_NAME="com.host.droidplugin_stub"- 1
- 1
(3) 集成完畢
4 開發(fā)host工程
(1) host的MainActivity.java代碼:
public class MainActivity extends AppCompatActivity {private TextView tvTest;private File[] plugins;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final TextView tvTest = (TextView) findViewById(R.id.tv_test);Button btnTest = (Button) findViewById(R.id.btn_test);btnTest.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {PackageManager pm = getPackageManager();Intent intent = pm.getLaunchIntentForPackage("com.plugin");intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}});//獲取插件File file = new File(Environment.getExternalStorageDirectory(), "/plugin");plugins = file.listFiles();//沒(méi)有插件if (plugins == null || plugins.length == 0) {return;}//安裝第一個(gè)插件else {try {PluginManager.getInstance().installPackage(plugins[0].getAbsolutePath(), PackageManagerCompat.INSTALL_REPLACE_EXISTING);} catch (RemoteException e) {e.printStackTrace();} tvTest.setText(plugins[0].getAbsolutePath());}}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
界面上就一個(gè)TextView和一個(gè)Button?
layout\activity_main.xml代碼如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
(2) 將插件apk放到/mnt/sdcard/plugin目錄下面,宿主apk運(yùn)行的時(shí)候會(huì)去找該目錄下面的文件,本例只是一個(gè)測(cè)試demo,所以默認(rèn)加載第一個(gè)文件。安裝插件的方法如下:
PluginManager.getInstance().installPackage(String filepath, int flags)- 1
- 1
說(shuō)明:安裝插件到插件系統(tǒng)中,filepath為插件apk路徑,flags可以設(shè)置為0,如果要更新插件,則設(shè)置為PackageManagerCompat.INSTALL_REPLACE_EXISTING返回值及其含義請(qǐng)參見(jiàn)PackageManagerCompat類中的相關(guān)字段
(3)?注意,坑在這里:?
DroidPlugin支持Android原生api,所以調(diào)用插件我就這樣寫:
- 1
- 2
- 1
- 2
其中com.plugin.action.start是和插件apk那邊的Activity的約定好的啟動(dòng)的action字符串?
然后,就呵呵了,一直卡在調(diào)用界面了,經(jīng)過(guò)一番折騰,發(fā)現(xiàn)?調(diào)用插件的時(shí)候只能使用下面方法:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
其中com.plugin是插件apk的包名,你也可以通過(guò)下面的代碼來(lái)獲取所有安裝的插件的包名:
List<PackageInfo> infos = PluginManager.getInstance().getInstalledPackages(0);- 1
- 1
也就是說(shuō):?
不能調(diào)用插件的任意Activity,只能從插件的啟動(dòng)方法調(diào)用,所以插件不可拆分,只能整塊整塊的調(diào)用
5 開發(fā)插件項(xiàng)目。
Plugin項(xiàng)目就是一個(gè)普通的apk,界面上有一個(gè)TextView,非常簡(jiǎn)單,不需要繼承或者依賴任何其他東西,就不貼出來(lái)了。運(yùn)行結(jié)果如下:
6 附錄:演示demo下載
本文中的演示demo已經(jīng)上傳到csdn,下載地址:
http://download.csdn.net/detail/fuchaosz/9585792
打開方法:?
(1) 先不要著急用android studio打開,先用文本編輯器打開DroidPluginTest/gradle/wrapper/gradle-wrapper.properties文件,修改下面這一行代碼:
- 1
- 1
將后面的 gradle-2.10-all.zip 修改為適合你的版本,至于哪個(gè)版本是適合你的,你可以先在AS中新建一個(gè)工程,然后到相同的目錄去查看。
(2) 修改DroidPluginTest/host/build.gradle文件,將下面這些變量修改為適合你的版本:
compileSdkVersion 24 buildToolsVersion "24.0.1"defaultConfig {..........minSdkVersion 15targetSdkVersion 24 }dependencies {............compile 'com.android.support:appcompat-v7:24.1.1' }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
至于哪些版本是適合你的,還是和上面一樣,在AS中新建一個(gè)工程對(duì)著修改。?
同理修改DroidPluginTest/plugin/build.gradle和DroidPluginTest/DroidPlugin/build.gradle
(3) 導(dǎo)入工程后,先運(yùn)行插件Plugin,生成apk,然后把生成的插件apk放到手機(jī)的/mnt/sdcard/plugin目錄下,apk位于下面的目錄:
build/outputs/apk- 1
- 1
接著再運(yùn)行宿主工程host即可了。?
如果你在實(shí)踐的過(guò)程中遇到問(wèn)題,歡迎給我留言,歡迎關(guān)注我的博客—梧桐那時(shí)雨。
7 總結(jié)
360的DroidPlugin是目前實(shí)現(xiàn)的比較好的插件化框架,插件apk完全與宿主隔離而且不受侵入,這點(diǎn)我非常喜歡,插件開發(fā)不需要額外學(xué)習(xí)成本,就決定是他了
8 轉(zhuǎn)載請(qǐng)注明來(lái)自”梧桐那時(shí)雨”的博客:http://blog.csdn.net/fuchaosz/article/details/51058058
總結(jié)
以上是生活随笔為你收集整理的[Android 插件化(二)] DroidPlugin 用法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [Android 插件化(一)] Dyn
- 下一篇: android sina oauth2.