Android 实现简单的插件化模块化
最近需要實現在android上開發插件,下面把一個簡單例子分享一下...
首先我們需要創建兩個工程,一個是主程序,一個是插件工程
1.首先在主程序中定義一個接口.?
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package com.mutour.testplugin; import android.content.Context; import android.view.View; public interface Plugin { ????public void load(); ????? ????public void create(Context context, View view); ????? ????public void create(View view); ????? ????public void show(); ????? ????public void hide(); ????? ????public View getView(); } |
2.接著在主程序中創建一個layout
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ????xmlns:tools="http://schemas.android.com/tools" ????android:layout_width="match_parent" ????android:layout_height="match_parent" ????android:orientation="vertical" ????android:paddingBottom="@dimen/activity_vertical_margin" ????android:paddingLeft="@dimen/activity_horizontal_margin" ????android:paddingRight="@dimen/activity_horizontal_margin" ????android:paddingTop="@dimen/activity_vertical_margin" ????tools:context=".MainActivity" > ????<LinearLayout ????????android:id="@+id/LinearLayoutContainer" ????????android:layout_width="match_parent" ????????android:layout_height="match_parent" ????????android:layout_weight="1" ????????android:orientation="vertical" > ????</LinearLayout> </LinearLayout> |
3.然后把主程序中的interface Plugin打包成jar.
?? 主程序工程右鍵,Export, 選擇Java-JAR file,(注意保存的路徑), 一路的next
????只選擇Plugin.java.
4.把生成的jar文件放到插件工程中?
5.在插件工程中寫一個layout文件R.layout.activity_number_plugin,隨便放點什么控件
6.在插件工程中寫插件類
?| 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | package com.mutour.testplugin.plugin; import com.mutour.testplugin.Plugin; import com.mutour.testplugin.plugin.R; import android.content.Context; import android.view.View; import android.widget.LinearLayout; public class NumberPlugin implements Plugin { ????private static final String TAG = "NumberPlugin"; ????private Context mContext; ????private View mView; ????private View viewNumber; ????/** ?????* 必須有一個無參構造函數,否則無法用newInstance()獲取句柄 ?????*/ ????public NumberPlugin() { ????} ????public void setContext(Context context) { ????????mContext = context; ????} ????public NumberPlugin(Context context) { ????????this(); ????????mContext = context; ????} ????@Override ????public void load() { ????} ????@Override ????public void show() { ????????((LinearLayout) mView).addView(viewNumber); ????} ????@Override ????public void hide() { ????????if (mView != null) ????????????((LinearLayout) mView).removeAllViews(); ????} ????@Override ????public void create(View view) { ????????mView = view; ????????viewNumber = View.inflate(mContext, R.layout.activity_number_plugin, ????????????????null); ????} ????@Override ????public void create(Context context, View view) { ????????mContext = context; ????????this.create(view); ????} ????@Override ????public View getView() { ????????return viewNumber; ????} } |
?
7.編譯工程,把bin目錄中的classes.dex文件放入手機的sd卡里.本文中放在sd卡根目錄中
8.編寫主程序調用插件dex文件
?| 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | package com.mutour.testplugin; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.mutour.testplugin.plugin.QwertyPlugin; import dalvik.system.DexClassLoader; import android.os.Bundle; import android.os.Environment; import android.annotation.SuppressLint; import android.app.ActionBar.LayoutParams; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; @SuppressLint("NewApi") public class MainActivity extends Activity { ????Plugin mPlugin; ????private LinearLayout mLinearLayoutContainer; ????@Override ????protected void onCreate(Bundle savedInstanceState) { ????????super.onCreate(savedInstanceState); ????????setContentView(R.layout.activity_main); ????????mLinearLayoutContainer = (LinearLayout) findViewById(R.id.LinearLayoutContainer); ????????String filepath = Environment.getExternalStorageDirectory().toString() ????????????????+ File.separator + "classes.dex"; ????????DexClassLoader cl = new DexClassLoader(filepath, MainActivity.this ????????????????.getDir("dex", 0).getAbsolutePath(), null, getClassLoader()); ????????Class libProviderClazz = null; ????????Plugin plugin = null; ????????try { ????????????Context pluginContext = createPackageContext( ????????????????????"com.mutour.testplugin.plugin", ????????????????????Context.CONTEXT_IGNORE_SECURITY); ????????????libProviderClazz = cl.loadClass("com.mutour.testplugin.plugin" ????????????????????+ ".NumberPlugin"); ????????????plugin = (Plugin) libProviderClazz.newInstance(); ????????????if (plugin != null) { ????????????????switchPlugin(pluginContext, plugin); ????????????} ????????} catch (Exception exception) { ????????????exception.printStackTrace(); ????????} ????} ????@Override ????public boolean onCreateOptionsMenu(Menu menu) { ????????getMenuInflater().inflate(R.menu.main, menu); ????????return true; ????} ????private void switchPlugin(Context context, Plugin plugin) { ????????if (mPlugin != null) { ????????????mPlugin.hide(); ????????} ????????plugin.load(); ????????plugin.create(context, mLinearLayoutContainer); ????????plugin.show(); ????????mPlugin = plugin; ????} } |
大功告成..............
其中有幾個需要注意的地方
1..需要先獲取dex的路徑,使用DexClassLoader加載這個dex,然后使用包名和類名獲取Class,然后使用newInstance獲取句柄,把類型轉換成Plugin
2.必須使用下面的方法獲取插件包的Context,否則無法獲取到插件包里的layout或其他資源
?| 1 2 3 | Context pluginContext = createPackageContext( ????????????????????"com.mutour.testplugin.plugin", ????????????????????Context.CONTEXT_IGNORE_SECURITY); |
?
........................................................................................................................................
下面連接是該主程序和插件程序的代碼..TestPlugin.rar是主程序 NumberPlugin.rar是插件程序
本方法是使用的dex方式,也可以使用apk方式安裝插件.....
總結
以上是生活随笔為你收集整理的Android 实现简单的插件化模块化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 插件化 模块化开发(ap
- 下一篇: 模块化以及插件化开发个人设计思路