zoukankan      html  css  js  c++  java
  • 转 android 动态加载 插件模型开发

    目前市面上的应用商店,不管是 apple 还是 android 平台, 一般只有一家商店。
    如果要动态添加商店,允许多家商店共存。
    搭建一个平台,多家应用商店可以加入。
    类似于商场与专卖店的关系。
    每个商店的业务由各自实现,但统一由商场来提供接口供用户选择。
    下面就来简单做个原型:
    1 ClassLoadTestMain  商场
    2 ClassLoadTestPlugin 商店

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

    接口定义:

    1. package com.pathfindeng.android.test;  
    2.   
    3. public interface  IPlugin {  
    4.       
    5.     public int add(int a, int b);  
    6.   
    7. }  


    商店实现接口:

    1. package com.pathfindeng.android.test.plugin;  
    2.   
    3. import com.pathfindeng.android.test.IPlugin;  
    4.   
    5. public class Plugin implements IPlugin{  
    6.       
    7.     public int add(int a, int b){  
    8.         return a + b;  
    9.     }  
    10. }  


    商场调用商店的实现:

    1. package com.pathfindeng.android.test.main;  
    2.   
    3. import com.pathfindeng.android.test.IPlugin;  
    4. import com.pathfindeng.android.test.main.R;  
    5.   
    6. import dalvik.system.DexClassLoader;  
    7. import dalvik.system.VMStack;  
    8. import android.app.Activity;  
    9. import android.os.Bundle;  
    10. import android.widget.TextView;  
    11. import android.widget.Toast;  
    12.   
    13. public class ClassLoadTestMainActivity extends Activity {  
    14.       
    15.       
    16.     TextView result;  
    17.     /** Called when the activity is first created. */  
    18.     @Override  
    19.     public void onCreate(Bundle savedInstanceState) {  
    20.         super.onCreate(savedInstanceState);  
    21.         setContentView(R.layout.main);  
    22.         result = (TextView)findViewById(R.id.result);  
    23.           
    24.     }  
    25.       
    26.     public void doInPlugin(){  
    27.           
    28.         String dexPath, dexOutputDir, libPath ,className;  
    29.         ClassLoader parent;  
    30.           
    31.         dexPath = "/data/app/com.pathfindeng.android.test.plugin-1.apk";  
    32.         dexOutputDir = "/data/data/com.pathfindeng.android.test.main";  
    33.           
    34.         libPath = "/data/data/com.pathfindeng.android.test.main/lib";  
    35.           
    36.         parent = ClassLoadTestMainActivity.this.getClassLoader();  
    37.           
    38.         //parent = VMStack.getCallingClassLoader();   
    39.           
    40.         DexClassLoader mDexClassLoader = new DexClassLoader(dexPath, dexOutputDir, libPath, parent);  
    41.           
    42.         className = "com.pathfindeng.android.test.plugin.Plugin";  
    43.           
    44.         try {  
    45.             Class mClass = mDexClassLoader.loadClass(className);  
    46.               
    47.             IPlugin mIPlugin = (IPlugin)mClass.newInstance();  
    48.               
    49.             int c;  
    50.             c = mIPlugin.add(100200);  
    51.               
    52.             result.setText("from plugin : "+c);  
    53.               
    54.             Toast.makeText(ClassLoadTestMainActivity.this"from plugin : "+c, Toast.LENGTH_LONG);  
    55.                           
    56.               
    57.         } catch (ClassNotFoundException e) {  
    58.             // TODO Auto-generated catch block   
    59.             e.printStackTrace();  
    60.         } catch (IllegalAccessException e) {  
    61.             // TODO Auto-generated catch block   
    62.             e.printStackTrace();  
    63.         } catch (InstantiationException e) {  
    64.             // TODO Auto-generated catch block   
    65.             e.printStackTrace();  
    66.         }  
    67.           
    68.           
    69.     }  
    70.   
    71.     /* (non-Javadoc) 
    72.      * @see android.app.Activity#onResume() 
    73.      */  
    74.     @Override  
    75.     protected void onResume() {  
    76.         // TODO Auto-generated method stub   
    77.         super.onResume();  
    78.           
    79.         doInPlugin();  
    80.     }  
    81.   
    82.     /* (non-Javadoc) 
    83.      * @see android.app.Activity#onDestroy() 
    84.      */  
    85.     @Override  
    86.     protected void onDestroy() {  
    87.         // TODO Auto-generated method stub   
    88.         super.onDestroy();  
    89.     }  
    90.       
    91. }  

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

    接下来做些改进。

    插件端 注册 固定 Action Name  

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

    服务器端 商场

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

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


    这样之前提到的 

    1. DexClassLoader(dexPath, dexOutputDir, libPath, parent)  

    
    
    

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

    待叙……

  • 相关阅读:
    C#操作ini配置文件和写入日志操作
    asp.net AJAX 定期刷新页面,然后,在 Timer 的事件中弹出窗口
    setInterval和setTimeout的区别
    检测远程URL是否存在
    SharePoint列表的模板类型中的BaseType参数和ListTemplate参数
    TCP中的Flag options
    jQuery基础教程摘录 Hello world
    SharePoint站点无法打开的问题
    SPQuery在引用field的时候要用internal name
    Windows Server 2008中用管理员的权限使用命令行来打开程序
  • 原文地址:https://www.cnblogs.com/lovelili/p/2306423.html
Copyright © 2011-2022 走看看