插件化理解

1.插件化的形式其实有挺多种,之前项目中使用的时apk安装的方法。开发比较简单,也可以做扩展,以及两个apk间共享数据,但用户体验比较差

2.其实应该比较正规的方法应该是classloadder进行动态加载。


下面是使用dexClassLoader进行动态加载的例子(需要注意的一点是:4.1系统上需要做一些特殊处理)


(笔记来源:

http://blog.zhourunsheng.com/2011/09/探秘腾讯android手机游戏平台之不安装游戏apk直接启动法/?utm_source=rss&utm_medium=rss&utm_campaign=%25e6%258e%25a2%25e7%25a7%2598%25e8%2585%25be%25e8%25ae%25afandroid%25e6%2589%258b%25e6%259c%25ba%25e6%25b8%25b8%25e6%2588%258f%25e5%25b9%25b3%25e5%258f%25b0%25e4%25b9%258b%25e4%25b8%258d%25e5%25ae%2589%25e8%25a3%2585%25e6%25b8%25b8%25e6%2588%258fapk%25e7%259b%25b4%25e6%258e%25a5%25e5%2590%25af%25e5%258a%25a8%25e6%25b3%2595


http://blog.csdn.net/yangjunjiezai/article/details/8668265)


//第一个应用,为主程序,进行正常安装,并调起要下载的插件/mnt/sdcard/TestB.apk


public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Bundle paramBundle = new Bundle();
				paramBundle.putBoolean("KEY_START_FROM_OTHER_ACTIVITY", true);
				String dexpath = "/mnt/sdcard/TestB.apk";
				String dexoutputpath = "dex";
				LoadAPK(paramBundle, dexpath, dexoutputpath);
			}
		});
	}

	public void LoadAPK(Bundle paramBundle, String dexpath, String dexoutputpath) {
		ClassLoader localClassLoader = ClassLoader.getSystemClassLoader();
		DexClassLoader localDexClassLoader;
		if(Build.VERSION.SDK_INT == 16){
			File dexOutputDir = MainActivity.this.getDir(dexoutputpath, 0);
			localDexClassLoader = 
					new DexClassLoader(dexpath, dexOutputDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader().getParent());
		}else
		localDexClassLoader = new DexClassLoader(dexpath,
				dexoutputpath, null, localClassLoader);
		try {
			PackageInfo plocalObject = getPackageManager()
					.getPackageArchiveInfo(dexpath, 1);

			if ((plocalObject.activities != null)
					&& (plocalObject.activities.length > 0)) {
				String activityname = plocalObject.activities[0].name;
				Log.d(TAG, "activityname = " + activityname);

				Class localClass = localDexClassLoader.loadClass(activityname);
				Constructor localConstructor = localClass
						.getConstructor(new Class[] {});
				Object instance = localConstructor.newInstance(new Object[] {});
				Log.d(TAG, "instance = " + instance);

				Method localMethodSetActivity = localClass.getDeclaredMethod(
						"setActivity", new Class[] { Activity.class });
				localMethodSetActivity.setAccessible(true);
				localMethodSetActivity.invoke(instance, new Object[] { this });

				Method methodonCreate = localClass.getDeclaredMethod(
						"onCreate", new Class[] { Bundle.class });
				methodonCreate.setAccessible(true);
				methodonCreate.invoke(instance, new Object[] { paramBundle });
			}
			return;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}


第二个应用不安装,直接下载即可,以下是代码:


private static final String TAG = "TestBActivity";
	private Activity otherActivity;
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		boolean b = false;
		if (savedInstanceState != null) {
			b = savedInstanceState.getBoolean("KEY_START_FROM_OTHER_ACTIVITY", false);
			if (b) {
				this.otherActivity.setContentView(new TBSurfaceView(
						this.otherActivity));
			}
		}
		if (!b) {
			super.onCreate(savedInstanceState);
			// setContentView(R.layout.main);
			setContentView(new TBSurfaceView(this));
		}
	}

	public void setActivity(Activity paramActivity) {
		Log.d(TAG, "setActivity..." + paramActivity);
		this.otherActivity = paramActivity;
	}
注意4.1上的特殊处理:

if(Build.VERSION.SDK_INT == 16){
			File dexOutputDir = MainActivity.this.getDir(dexoutputpath, 0);
			localDexClassLoader = 
					new DexClassLoader(dexpath, dexOutputDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader().getParent());
		}else
		localDexClassLoader = new DexClassLoader(dexpath,
				dexoutputpath, null, localClassLoader);




你可能感兴趣的:(插件化)