package org.bbs.osgi.activity; import java.nio.MappedByteBuffer; import org.bbs.osgi.activity.ReflectUtil.ActivityReflectUtil; import org.osgi.framework.Bundle; import org.osgi.framework.wiring.BundleWiring; import android.app.Application; import android.content.Context; import android.content.ContextWrapper; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.text.TextUtils; import android.util.Log; import android.view.ContextThemeWrapper; /** * when bundle resource is ready, return this, otherwise, return normally. * @author bysong * */ public class LazyContext extends ContextWrapper //ContextThemeWrapper { private static final String TAG = LazyContext.class.getSimpleName(); private static String mPackageName; private Resources mResource; private ClassLoader mClassLoader; private ClassLoader mMergedClassLoader; private PackageManager mPackageManager; private Application mApp; private Theme mTargetTheme; private int mTargetThemeId; public LazyContext(Context base) { super(base); // this(base, 0); } // public LazyContext(Context base, int themeResId) { // super(base, themeResId); // } public static void bundleReady(LazyContext LazyContext, Bundle bundle, Resources res, String packageName) { LazyContext.mClassLoader = bundle.adapt(BundleWiring.class).getClassLoader(); LazyContext.mResource = res; mPackageName = packageName; } public void packageManagerReady(PackageManager pm) { mPackageManager = pm; } public void applicationReady(Application app){ mApp = app; } public void packageNameReady(String packageName) { mPackageName = packageName; } public void themeReady(int theme) { mTargetThemeId = theme; } public void resReady(Resources res) { mResource = res; } public void classLoaderReady(ClassLoader classloader) { mClassLoader = classloader; } @Override public Theme getTheme() { if (null != mTargetTheme) { return mTargetTheme; } if (mResource != null) { if (mTargetThemeId > 0) { if (mTargetTheme == null) { mTargetTheme = mResource.newTheme(); } mTargetTheme.applyStyle(mTargetThemeId, true); return mTargetTheme; } } return super.getTheme(); } @Override public String getPackageName() { String pName = doGetPackageName(); // Log.d(TAG, "getPackageName(). packageName: " + pName); return pName; } public String doGetPackageName() { // new Exception("stack info").printStackTrace(); if (!TextUtils.isEmpty(mPackageName)) { return mPackageName; } return super.getPackageName(); } @Override public Resources getResources() { if (null == mResource) { return super.getResources(); } else { return mResource; } } @Override public AssetManager getAssets() { if (null != mResource) { if (mResource instanceof ResourcesMerger) { Resources r = ((ResourcesMerger)mResource).mFirst; return getAsset(r); } } return super.getAssets(); } private AssetManager getAsset(Resources r) { return (AssetManager) ReflectUtil.getFiledValue(Resources.class, r, "mAssets"); } @Override public ClassLoader getClassLoader() { ClassLoader cl = super.getClassLoader(); if (mClassLoader != null) { if (mMergedClassLoader == null) { mMergedClassLoader = new MergedClassLoader(cl, mClassLoader); } cl = mMergedClassLoader; } return cl; } @Override public PackageManager getPackageManager() { PackageManager pm = doGetPackageManager(); // Log.d(TAG, "pm: " + pm); return pm; } public PackageManager doGetPackageManager() { // new Exception("stack info").printStackTrace(); if (mPackageManager != null) { return mPackageManager; } return super.getPackageManager(); } @Override public Context getApplicationContext() { if (mApp != null) { return mApp; } return super.getApplicationContext(); } @Override public SharedPreferences getSharedPreferences(String name, int mode) { SharedPreferences pref = super.getSharedPreferences(name, mode); Log.d(TAG, "SharedPreferences(). name: " + name + " pref: " + pref); return pref; } class MergedAssetManager // extends AssetManager { } class MergedClassLoader extends ClassLoader { private ClassLoader mMinor; private ClassLoader mMajor; MergedClassLoader(ClassLoader major, ClassLoader minor) { mMajor = major; mMinor = minor; } @Override protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { try { return mMajor.loadClass(className); } catch (Exception e) { return mMinor.loadClass(className); } } } }