package com.dianping.example.fragmentloader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.res.AssetManager; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.os.Bundle; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.Toast; import dalvik.system.DexClassLoader; public class FragmentLoader extends Activity { private AssetManager asm; private Resources res; private Theme thm; private ClassLoader cl; @Override protected void onCreate(Bundle savedInstanceState) { if ("com.dianping.intent.action.LOAD_FRAGMENT".equals(getIntent() .getAction())) { // we need to setup environment before super.onCreate try { String path = getIntent().getStringExtra("path"); InputStream ins = MyApplication.instance().getAssets() .open(path); byte[] bytes = new byte[ins.available()]; ins.read(bytes); ins.close(); File f = new File(MyApplication.instance().getFilesDir(), "dex"); f.mkdir(); f = new File(f, "FL_" + Integer.toHexString(path.hashCode()) + ".apk"); FileOutputStream fos = new FileOutputStream(f); fos.write(bytes); fos.close(); File fo = new File(MyApplication.instance().getFilesDir(), "dexout"); fo.mkdir(); DexClassLoader dcl = new DexClassLoader(f.getAbsolutePath(), fo.getAbsolutePath(), null, super.getClassLoader()); cl = dcl; try { AssetManager am = (AssetManager) AssetManager.class .newInstance(); am.getClass().getMethod("addAssetPath", String.class) .invoke(am, f.getAbsolutePath()); asm = am; } catch (Exception e) { throw new RuntimeException(e); } Resources superRes = super.getResources(); res = new Resources(asm, superRes.getDisplayMetrics(), superRes.getConfiguration()); thm = res.newTheme(); thm.setTo(super.getTheme()); } catch (Exception e) { e.printStackTrace(); } } super.onCreate(savedInstanceState); FrameLayout rootView = new FrameLayout(this); rootView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); rootView.setId(android.R.id.primary); setContentView(rootView); if (savedInstanceState != null) return; if ("com.dianping.intent.action.LOAD_FRAGMENT".equals(getIntent() .getAction())) { try { String fragmentClass = getIntent().getStringExtra("class"); Fragment f = (Fragment) getClassLoader().loadClass( fragmentClass).newInstance(); FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.add(android.R.id.primary, f); ft.commit(); } catch (Exception e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); } } else { Fragment f = new ListApkFragment(); FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.add(android.R.id.primary, f); ft.commit(); } } @Override public AssetManager getAssets() { return asm == null ? super.getAssets() : asm; } @Override public Resources getResources() { return res == null ? super.getResources() : res; } @Override public Theme getTheme() { return thm == null ? super.getTheme() : thm; } @Override public ClassLoader getClassLoader() { return cl == null ? super.getClassLoader() : cl; } }