网上找了很多关于插件式开发的资料 最值得研究意义的两种开源开发插件框架http://www.oschina.net/p/cjframeforandroid 与http://www.oschina.net/p/xcombine 另外还有一种非常简单的通过sharedUserId方式去实现。接下来讲的就是最方便的通过sharedUserId去实现。
思路:在主app中与次app中设置同样的sharedUserId,在主app中通过这个id 找到其他次app的包名,通过包名开启其他次app。
需要注意的是 次app中的主activity的action是包名并且category设置成默认的。
demo 下载地址http://download.csdn.net/detail/u012303938/8642017
上代码: 主app通过一个按钮去调用一个次app(插件)。
MainActivity.class
package com.example.plugin;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1=(Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
attachPlugin(findPlugins());
}
});
}
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(!"main.plugin".equals(sharedUserId)||"com.example.plugin".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);
plug.setPrcessName(prcessName);
plug.setSharedUserId(sharedUserId);
plugins.add(plug);
}
return plugins;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void attachPlugin(List<PluginBean> plugins){
Intent intent=new Intent();
if(plugins!=null&&plugins.size()>0){
intent.setAction(plugins.get(0).getPakageName());
Toast.makeText(this, plugins.get(0).getPakageName(), 1).show();
startActivity(intent);
}else{
Toast.makeText(this, "没有找到插件", 1).show();
}
}
}
存放插件的数据 pluginbean.class
package com.example.plugin;
public class PluginBean {
private String pakageName;
private String label;
private String sharedUserId;
public String getSharedUserId() {
return sharedUserId;
}
public void setSharedUserId(String sharedUserId) {
this.sharedUserId = sharedUserId;
}
public String getPrcessName() {
return prcessName;
}
public void setPrcessName(String prcessName) {
this.prcessName = prcessName;
}
private String prcessName;
public String getPakageName() {
return pakageName;
}
public void setPakageName(String pakageName) {
this.pakageName = pakageName;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.plugin"
android:sharedUserId="main.plugin"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.plugin.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.calss
package com.example.plug_test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.GridView;
import android.widget.SimpleAdapter;
public class MainActivity extends Activity {
private GridView gridView1;
private ArrayList<Map<String, Object>> list=new ArrayList<Map<String,Object>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findView();
}
private void findView() {
// TODO Auto-generated method stub
for(int i=0;i<5;i++){
Map<String, Object> map=new HashMap<String, Object>();
map.put("apkName", "name"+i);
map.put("icon", R.drawable.ic_launcher);
list.add(map);
}
gridView1=(GridView) findViewById(R.id.gridView1);
SimpleAdapter adapter=new SimpleAdapter(this, list, R.layout.grid_item,
new String[]{"apkName","icon"}, new int []{R.id.tv_name,R.id.img});
gridView1.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.plug_test"
android:sharedUserId="main.plugin"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.plug_test.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="com.example.plug_test" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
原文:http://blog.csdn.net/u012303938/article/details/45337457