android 动态加载 插件模型开发

来源:互联网 发布:龙腾网络传奇 编辑:程序博客网 时间:2024/05/23 01:19
目前市面上的应用商店,不管是 apple 还是 android 平台, 一般只有一家商店。
如果要动态添加商店,允许多家商店共存。
搭建一个平台,多家应用商店可以加入。
类似于商场与专卖店的关系。
每个商店的业务由各自实现,但统一由商场来提供接口供用户选择。
下面就来简单做个原型:
1 ClassLoadTestMain  商场
2 ClassLoadTestPlugin 商店

3 PluginInterface 商场提供给商店的接口


接口定义:

package com.pathfindeng.android.test;public interface  IPlugin {public int add(int a, int b);}

商店实现接口:

package com.pathfindeng.android.test.plugin;import com.pathfindeng.android.test.IPlugin;public class Plugin implements IPlugin{public int add(int a, int b){return a + b;}}

商场调用商店的实现:

package com.pathfindeng.android.test.main;import com.pathfindeng.android.test.IPlugin;import com.pathfindeng.android.test.main.R;import dalvik.system.DexClassLoader;import dalvik.system.VMStack;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;import android.widget.Toast;public class ClassLoadTestMainActivity extends Activity {TextView result;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        result = (TextView)findViewById(R.id.result);            }        public void doInPlugin(){        String dexPath, dexOutputDir, libPath ,className;    ClassLoader parent;        dexPath = "/data/app/com.pathfindeng.android.test.plugin-1.apk";    dexOutputDir = "/data/data/com.pathfindeng.android.test.main";        libPath = "/data/data/com.pathfindeng.android.test.main/lib";        parent = ClassLoadTestMainActivity.this.getClassLoader();        //parent = VMStack.getCallingClassLoader();        DexClassLoader mDexClassLoader = new DexClassLoader(dexPath, dexOutputDir, libPath, parent);        className = "com.pathfindeng.android.test.plugin.Plugin";        try {Class mClass = mDexClassLoader.loadClass(className);IPlugin mIPlugin = (IPlugin)mClass.newInstance();int c;c = mIPlugin.add(100, 200);result.setText("from plugin : "+c);Toast.makeText(ClassLoadTestMainActivity.this, "from plugin : "+c, Toast.LENGTH_LONG);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();}            }/* (non-Javadoc) * @see android.app.Activity#onResume() */@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();doInPlugin();}/* (non-Javadoc) * @see android.app.Activity#onDestroy() */@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();}    }

从上面的代码看,调用插件还是强制定义的,不够人性

接下来做些改进。

插件端 注册 固定 Action Name  

<activity android:name=".商店Activity" android:label="@string/app_name">            <intent-filter>                <action android:name="接口指定固定 Action Name" />            </intent-filter></activity>


服务器端 商场

利用 PackageManager 查询所有注册了接口定义的 Action Name 的商店,并获得信息。

Intent intent = new Intent(Constants.ACTION_PLUGIN, null);PackageManager pm = mContext.getPackageManager();List<ResolveInfo> plugins = pm.queryIntentActivities(intent, 0);

这样之前提到的 

DexClassLoader(dexPath, dexOutputDir, libPath, parent)

参数就不需要 手动指定了。



待叙……



原创粉丝点击