轉 android 動態載入 外掛程式模型開發

來源:互聯網
上載者:User

目前市面上的市集,不管是 apple 還是 android 平台, 一般只有一家商店。
如果要動態添加商店,允許多家商店共存。
搭建一個平台,多家市集可以加入。
類似於商場與專賣店的關係。
每個商店的業務由各自實現,但統一由商場來提供介面供使用者選擇。
下面就來簡單做個原型:
1 ClassLoadTestMain  商場
2 ClassLoadTestPlugin 商店

3 PluginInterface 商場提供給商店的介面

 

介面定義:

 

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

package com.pathfindeng.android.test;</p><p>public interface IPlugin {</p><p>public int add(int a, int b);</p><p>}
商店實現介面:

 

 

view plaincopy to clipboardprint?
  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. }  

package com.pathfindeng.android.test.plugin;</p><p>import com.pathfindeng.android.test.IPlugin;</p><p>public class Plugin implements IPlugin{</p><p>public int add(int a, int b){<br />return a + b;<br />}<br />}
商場調用商店的實現:

 

 

view plaincopy to clipboardprint?
  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(100, 200);  
  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. }  

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

從上面的代碼看,調用外掛程式還是強制定義的,不夠人性

接下來做些改進。

外掛程式端 註冊 固定 Action Name  

 

view plaincopy to clipboardprint?
  1. <activity android:name=".商店Activity" android:label="@string/app_name">  
  2.             <intent-filter>  
  3.                 <action android:name="介面指定固定 Action Name" />  
  4.             </intent-filter>  
  5. </activity>  

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

 

 

伺服器端 商場

利用 PackageManager 查詢所有註冊了介面定義的 Action Name 的商店,並獲得資訊。

 

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

Intent intent = new Intent(Constants.ACTION_PLUGIN, null);<br />PackageManager pm = mContext.getPackageManager();<br />List<ResolveInfo> plugins = pm.queryIntentActivities(intent, 0);
這樣之前提到的 

 

view plaincopy to clipboardprint?
  1. DexClassLoader(dexPath, dexOutputDir, libPath, parent)  

DexClassLoader(dexPath, dexOutputDir, libPath, parent)

 


 

參數就不需要 手動指定了。

 

 

待敘……

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.