package com.dianping.loader;
import java.io.File;
import java.util.HashMap;
import android.text.TextUtils;
import com.dianping.app.MyApplication;
import com.dianping.loader.model.FileSpec;
import com.dianping.loader.model.SiteSpec;
import dalvik.system.DexClassLoader;
public class MyClassLoader extends DexClassLoader {
FileSpec file;
MyClassLoader[] deps;
MyClassLoader(FileSpec file, String dexPath, String optimizedDirectory,
String libraryPath, ClassLoader parent, MyClassLoader[] deps) {
super(dexPath, optimizedDirectory, libraryPath, parent);
this.file = file;
this.deps = deps;
}
@Override
protected Class<?> loadClass(String className, boolean resolve)
throws ClassNotFoundException {
Class<?> clazz = findLoadedClass(className);
if (clazz != null)
return clazz;
try {
clazz = getParent().loadClass(className);
} catch (ClassNotFoundException e) {
}
if (clazz != null)
return clazz;
if (deps != null) {
for (MyClassLoader c : deps) {
try {
clazz = c.findClass(className);
break;
} catch (ClassNotFoundException e) {
}
}
}
if (clazz != null)
return clazz;
clazz = findClass(className);
return clazz;
}
static final HashMap<String, MyClassLoader> loaders = new HashMap<String, MyClassLoader>();
/**
* return null if not available on the disk
*/
public static MyClassLoader getClassLoader(SiteSpec site, FileSpec file) {
MyClassLoader cl = loaders.get(file.id());
if (cl != null)
return cl;
String[] deps = file.deps();
MyClassLoader[] ps = null;
if (deps != null) {
ps = new MyClassLoader[deps.length];
for (int i = 0; i < deps.length; i++) {
FileSpec pf = site.getFile(deps[i]);
if (pf == null)
return null;
MyClassLoader l = getClassLoader(site, pf);
if (l == null)
return null;
ps[i] = l;
}
}
File dir = MyApplication.instance().getFilesDir();
dir = new File(dir, "repo");
if (!dir.isDirectory())
return null;
dir = new File(dir, file.id());
File path = new File(dir, TextUtils.isEmpty(file.md5()) ? "1.apk"
: file.md5() + ".apk");
if (!path.isFile())
return null;
File outdir = new File(dir, "dexout");
outdir.mkdir();
cl = new MyClassLoader(file, path.getAbsolutePath(),
outdir.getAbsolutePath(), null, MyApplication.instance()
.getClassLoader(), ps);
loaders.put(file.id(), cl);
return cl;
}
}