1.入口
protected void startActivity(Class> clazz) {
Intent intent = new Intent(this,clazz);
startActivity(intent);
}
2. 调用startActivityForResult
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
3. 执行execStartActivity
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
4. 构建代理管理类
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
//构建manager代理类
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
...
}
5.使用binder调用底层管理类
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
//!!!
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
然后的然后...
6.回到ActivityThread的performLaunchActivity()方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//核心代码!!!
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
}
7.创建类的实例
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
protected Class> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
...
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
//最终执行
c = findClass(name);
}
}
return c;
}
Classload通过类名找到相应的.class文件,然后通过反射创建出类的实例
8.寻找findClass源码
查看源码发现,Classload并没有实现findClass方法,此外通过之前传入的cl对象发现存在这样的继承关系关系:
Classload→BaseDexClassLoader→PathClassLoader
9.查找findClass的具体实现代码
网址:http://androidxref.com/
找到BaseDexClassLoader
@Override
protected Class> findClass(String name) throws ClassNotFoundException {
List suppressedExceptions = new ArrayList();
//核心代码!!!
Class c = pathList.findClass(name, suppressedExceptions);
if (c == null) {
ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + pathList);
for (Throwable t : suppressedExceptions) {
cnfe.addSuppressed(t);
}
throw cnfe;
}
return c;
}
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
String libraryPath, ClassLoader parent) {
super(parent);
this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
}
原理:通过名字在一个DexPathList集合中找到相应的.class文件
public Class findClass(String name, List suppressed) {
for (Element element : dexElements) {
DexFile dex = element.dexFile;
if (dex != null) {
Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
if (clazz != null) {
return clazz;
}
}
}
if (dexElementsSuppressedExceptions != null) {
suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
}
return null;
}
dex文件由Element数组管理,通过遍历dexElements,然后通过传入的class名字就可以找到相应的class文件
10.写在最后
此文仅作为学习笔记