- Android 触摸屏事件派发机制详解与源码分析一 View 篇
- Android 触摸屏事件派发机制详解与源码分析二 ViewGroup 篇
- Android 触摸屏事件派发机制详解与源码分析三 Activity 篇
- Android 应用 setContentView 与 LayoutInflater 加载解析机制源码分析
- Android 应用 Context 详解及源码解析
- Android 异步消息处理机制详解及源码分析
- Android 应用 Activity、Dialog、PopWindow、Toast 窗口添加机制及源码分析
- Android ListView 工作原理完全解析,带你从源码的角度彻底理解
- Activity 启动过程全解析
- Android 应用 AsyncTask 处理机制详解及源码分析
- 说说 PendingIntent 的内部机制
- Android Activity.startActivity 流程简介
- Activity 界面显示全解析
- 框架层理解 Activity 生命周期(APP 启动过程)
- APK 安装过程及原理详解
- Android 构建过程简述
- Android 应用层 View 绘制流程与源码分析
送给你们的彩蛋
不要使用 startActivityForResult(intent,RESULT_OK)
这是因为 startActivity() 是这样实现的
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);
}
}
而
public static final int RESULT_OK = -1;
所以
startActivityForResult(intent,RESULT_OK) = startActivity()
你不可能从 onActivityResult() 里面收到任何回调。而这个问题是相当难以被发现的,就是因为这个坑,我工作一年多来第一次加班到 9 点 (ˇˍˇ)
一个 App 的程序入口到底是什么?
是 ActivityThread.main()。
整个 App 的主线程的消息循环是在哪里创建的?
是在 ActivityThread 初始化的时候,就已经创建消息循环了,所以在主线程里面创建 Handler 不需要指定 Looper,而如果在其他线程使用 Handler,则需要单独使用 Looper.prepare() 和 Looper.loop() 创建消息循环。
public static void main(String[] args) {
...ignore some code...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
...ignore some code...
}
Application 是在什么时候创建的?onCreate() 什么时候调用的?
也是在 ActivityThread.main() 的时候,再具体点呢,就是在 thread.attach(false) 的时候。
看你的表情,不信是吧!凯子哥带你溜溜~
我们先看一下 ActivityThread.attach()
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
//普通 App 进这里
if (!system) {
...ignore some code...
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
//这个分支在 SystemServer 加载的时候会进入,通过调用
// private void createSystemContext() {
// ActivityThread activityThread = ActivityThread.systemMain();
//}
// public static ActivityThread systemMain() {
// if (!ActivityManager.isHighEndGfx()) {
// HardwareRenderer.disable(true);
// } else {
// HardwareRenderer.enableForegroundTrimming();
// }
// ActivityThread thread = new ActivityThread();
// thread.attach(true);
// return thread;
// }
}
}
这里需要关注的就是 mgr.attachApplication(mAppThread),这个就会通过 Binder 调用到 AMS 里面对应的方法
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
然后就是
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
}
thread 是 IApplicationThread,实际上就是 ApplicationThread 在服务端的代理类 ApplicationThreadProxy,然后又通过 IPC 就会调用到
ApplicationThread 的对应方法
private class ApplicationThread extends ApplicationThreadNative {
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
...ignore some code...
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
}
我们需要关注的其实就是最后的 sendMessage(),里面有函数的编号 H.BIND_APPLICATION,然后这个 Messge 会被 H 这个 Handler 处理
private class H extends Handler {
...ignore some code...
public static final int BIND_APPLICATION = 110;
...ignore some code...
public void handleMessage(Message msg) {
switch (msg.what) {
...ignore some code...
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...ignore some code...
}
}
最后就在下面这个方法中,完成了实例化,拨那个企鹅通过 mInstrumentation.callApplicationOnCreate 实现了 onCreate() 的调用。
private void handleBindApplication(AppBindData data) {
try {
...ignore some code...
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...ignore some code...
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) { }
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
data.info 是一个 LoadeApk 对象。
LoadeApk.data.info.makeApplication()
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) { }
mActivityThread.mAllApplications.add(app);
mApplication = app;
//传进来的是 null,所以这里不会执行,onCreate 在上一层执行
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
}
}
...ignore some code...
}
return app;
}
所以最后还是通过 Instrumentation.makeApplication() 实例化的,这个老板娘真的很厉害呀!
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
而且通过反射拿到 Application 对象之后,直接调用 attach(),所以 attach() 调用是在 onCreate() 之前的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论