package com.plugin.core;

import java.io.File;
import java.lang.reflect.Method;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Build;
import android.util.Log;
import dalvik.system.DexClassLoader;

public class PluginCreator {

	private static final String LOG_TAG = PluginCreator.class.getSimpleName();

	private PluginCreator() {
	}

	/**
	 * 根据插件apk文件，创建插件dex的classloader
	 * 
	 * @param absolutePluginApkPath
	 *            插件apk文件路径
	 * @return
	 */
	public static DexClassLoader createPluginClassLoader(String absolutePluginApkPath) {
		return new DexClassLoader(absolutePluginApkPath, new File(absolutePluginApkPath).getParent(), null,
				PluginLoader.class.getClassLoader());
	}

	/**
	 * 根据插件apk文件，创建插件资源文件，同时绑定宿主程序的资源，这样就可以在插件中使用宿主程序的资源。
	 * 
	 * @param application
	 *            宿主程序的Application
	 * @param absolutePluginApkPath
	 *            插件apk文件路径
	 * @return
	 */
	public static Resources createPluginResource(Application application, String absolutePluginApkPath) {
		try {
			AssetManager assetMgr = AssetManager.class.newInstance();
			Method addAssetPaths = AssetManager.class.getDeclaredMethod("addAssetPaths", String[].class);

			String[] assetPaths = new String[2];

			//不可更改顺序否则不能兼容4.x
			assetPaths[0] = application.getApplicationInfo().sourceDir;
			assetPaths[1] = absolutePluginApkPath;

			addAssetPaths.invoke(assetMgr, new Object[] { assetPaths });

			Resources mainRes = application.getResources();
			Resources pluginRes = new Resources(assetMgr, mainRes.getDisplayMetrics(), mainRes.getConfiguration());

			Log.e(LOG_TAG, "create Plugin Resource from: " + assetPaths[0] + ", " + assetPaths[1]);

			return pluginRes;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 创建插件apk的Context。
	 * 如果插件是运行在普通的Activity中，那么插件中需要使用context的地方，都需要使用此方法返回的Context
	 * 
	 * @param application
	 * @param pluginRes
	 * @param pluginClassLoader
	 * @return
	 */
	public static Context createPluginApplicationContext(Application application, Resources pluginRes,
			DexClassLoader pluginClassLoader) {
		return new PluginContextTheme(application, pluginRes, pluginClassLoader);
	}

	/**
	 * 创建插件apk的Activity context，
	 * 如果用此Context替换宿主程序的Activity的baseContext，那么插件中需要使用context的地方，和非插件开发时完全一致。
	 * 即开发出来的插件代码，和普通的应用程序代码没有区别。 这个方法由于传入了Activity，为了避免泄漏，切记不可长久保持催此方法返回值的引用
	 * 
	 * @param activity
	 * @param pluginContext
	 * @return
	 */
	public static Context createPluginActivityContext(Activity activity, Context pluginContext) {
		return new PluginContextTheme(activity, pluginContext.getResources(), pluginContext.getClassLoader());
	}

}

@@ -1834,16 +1834,899 @@
 1%5D);%0D%0A%0D%0A
+%09%09%09return pluginRes;%0D%0A%09%09%7D catch (Exception e) %7B%0D%0A%09%09%09e.printStackTrace();%0D%0A%09%09%7D%0D%0A%09%09return null;%0D%0A%09%7D%0D%0A%09%0D%0A%09/*package*/ static Resources createPluginResourceFor5(Application application, String absolutePluginApkPath) %7B%0D%0A%09%09try %7B%0D%0A%09%09%09AssetManager assetMgr = AssetManager.class.newInstance();%0D%0A%09%09%09Method addAssetPaths = AssetManager.class.getDeclaredMethod(%22addAssetPaths%22, String%5B%5D.class);%0D%0A%0D%0A%09%09%09String%5B%5D assetPaths = new String%5B2%5D;%0D%0A%0D%0A%09%09%09//%E4%B8%8D%E5%8F%AF%E6%9B%B4%E6%94%B9%E9%A1%BA%E5%BA%8F%E5%90%A6%E5%88%99%E4%B8%8D%E8%83%BD%E5%85%BC%E5%AE%B94.x%0D%0A%09%09%09assetPaths%5B0%5D = absolutePluginApkPath;%0D%0A%09%09%09assetPaths%5B1%5D = application.getApplicationInfo().sourceDir;%0D%0A%0D%0A%09%09%09addAssetPaths.invoke(assetMgr, new Object%5B%5D %7B assetPaths %7D);%0D%0A%0D%0A%09%09%09Resources mainRes = application.getResources();%0D%0A%09%09%09Resources pluginRes = new Resources(assetMgr, mainRes.getDisplayMetrics(), mainRes.getConfiguration());%0D%0A%0D%0A%09%09%09Log.e(LOG_TAG, %22create Plugin Resource from: %22 + assetPaths%5B0%5D + %22, %22 + assetPaths%5B1%5D);%0D%0A%0D%0A
 %09%09%09retur

update creator for 5.x and 2.x