.... <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.igeek.plugintest.main" <!-- 就是這句關鍵代碼 --> android:sharedUserId="org.igeek.plugintest" android:versionCode="1" android:versionName="1.0"> .....
public class AndoirdpluginActivity extends ActivityGroup implements OnClickListener ,OnScrollCompleteListener{ private LinearLayout llMainLayout; //workspace,看看luncher的源碼,這個就是桌面那個多屏的實現 private WorkSpace wkMain; private Button btnFindPlugins; private CheckBox chbAttachMain; private LocalActivityManager m_ActivityManager; //這個bean的集合,就至關於插件的描述集合 //每一個bean也就是一個插件的各類描述 private List<PluginBean> plugins; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); llMainLayout=(LinearLayout) findViewById(R.id.main_llMainLayout); wkMain=(WorkSpace) findViewById(R.id.main_wkMain); btnFindPlugins=(Button) findViewById(R.id.main_btnFindPlugins); chbAttachMain=(CheckBox) findViewById(R.id.main_chbAttachMain); m_ActivityManager = getLocalActivityManager(); wkMain.setOnScrollCompleteLinstenner(this); btnFindPlugins.setOnClickListener(this); } @Override public void onClick(View v) { attachPlugin(findPlugins()); btnFindPlugins.setVisibility(View.GONE); } /** * 加載插件列表 * @param plugins */ private void attachPlugin(final List<PluginBean> plugins){ Log.e("ydt", " "); Log.e("ydt", "----- 列出插件"); this.plugins=plugins; for(final PluginBean plugin:plugins){ Button btn=new Button(this); btn.setTextColor(Color.RED); btn.setText(plugin.getLabel()); llMainLayout.addView(btn); //添加事件 btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean isAttack=chbAttachMain.isChecked(); Intent it=new Intent(); it.setAction(plugin.getPakageName()); //是否附加爲view if(isAttack){ //這裏偷下懶,這是演示插件做爲view附加到主程序中的 for(PluginBean plugin:plugins){ Intent itt=new Intent(); itt.setAction(plugin.getPakageName()); ViewGroup view=(ViewGroup) (m_ActivityManager.startActivity("", itt)).getDecorView(); wkMain.addView(view); } //一次性附加完畢算了,而後把按鈕都刪了,看着清淨,這幾個不是重點 llMainLayout.removeAllViews(); chbAttachMain.setVisibility(View.GONE); wkMain.setToScreen(0); }else{ //這裏,不會把插件的窗體附加到主程序中,純粹無用的演示 startActivity(it); } } }); } } /** * 查找插件 * @return */ private List<PluginBean> findPlugins(){ List<PluginBean> plugins=new ArrayList<PluginBean>(); //遍歷包名,來獲取插件 PackageManager pm=getPackageManager(); List<PackageInfo> pkgs=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); for(PackageInfo pkg :pkgs){ //包名 String packageName=pkg.packageName; String sharedUserId= pkg.sharedUserId; //sharedUserId是開發時約定好的,這樣判斷是否爲本身人 if(!"org.igeek.plugintest".equals(sharedUserId)||"org.igeek.plugintest.main".equals(packageName)) continue; //進程名 String prcessName=pkg.applicationInfo.processName; //label,也就是appName了 String label=pm.getApplicationLabel(pkg.applicationInfo).toString(); PluginBean plug=new PluginBean(); plug.setLabel(label); plug.setPakageName(packageName); plugins.add(plug); } return plugins; } /** * WorkSpace滾動到那個屏,會觸發這個事件 * 而worksapce中每一屏又是一個插件 * 這個事件是用來列出當前屏幕插件所提供的應用,而且讓用戶調用 */ @Override public void onScrollComplete(final ScrollEvent e) { try { final Context context = createPackageContext(plugins.get(e.curScreen).getPakageName(), Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY); llMainLayout.removeAllViews(); //這幾行,經過反射獲取了當前插件的描述信息,如同大部分框架的xml同樣,這裏算是模擬了一下IOC控制反轉 Class clazz=context.getClassLoader().loadClass(plugins.get(e.curScreen).getPakageName()+".PluginApplication"); Object o=clazz.newInstance(); Map<String,List<String>> r=(Map<String, List<String>>) clazz.getMethod("getDesciption").invoke(o); List<String> classes=r.get("classes"); List<String> methods=r.get("methods"); //這裏,根據得到的插件所提供的功能,來生成幾個按鈕顯示,供咱們調用 for(final String clas:classes){ for(final String method:methods){ Button btn=new Button(this); btn.setText(clas+" -> "+method+" 執行"); //點擊後,就執行插件所提供的方法 btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { Class c=context.getClassLoader().loadClass(plugins.get(e.curScreen).getPakageName()+"."+clas); Object o1=c.newInstance(); //這裏注意,context實際上就是句柄,這裏若是涉及到窗體,plugin的句柄實際上是不行的,由於它沒有能夠 //依附的窗體 //這個context是plugin的,經過測試,dialog這類行不通,Toast是能夠的,由於 //Toast是依附於屏幕主窗口的 //c.getMethod(method,Context.class).invoke(o1,context); //這裏則傳遞的是主程序的句柄 c.getMethod(method,Context.class).invoke(o1,AndoirdpluginActivity.this); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); llMainLayout.addView(btn); } } } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }
單擊下載java
最後 本人水平有限,不免有些疏漏或者錯誤,還請指正!!!linux