Activity启动流程、Looper及Handler
2015-07-08 15:39
344 查看
android.app.ActivityManager
ActivityManager负责ActivityThread的创建,Activity生命周期的维护android.app.ActivityThread
该类中的main方法是Android应用的入口,每个apk中都包含一个且仅有一个ActivityThread类,并作为应用的主线程类。ActivityThread类管理主线程(UI线程)的执行,负责调度和运行应用中的activity,广播,以及其他操作。ActivityThread.main方法
public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); // //为当前线程(主线程)创建一个Looper对象 ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); //为当前线程设置Handler } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); // 执行从消息队列中获取Message,并调用Handler进行处理的无限循环;所有和主线程相关的消息处理都在该方法中执行 throw new RuntimeException("Main thread loop unexpectedly exited"); }
ActivityThread中比较重要的字段
final ApplicationThread mAppThread = new ApplicationThread();
mAppThread字段通过binder和AMS通信,并将AMS调用封装成消息,通过上述sMainThreadHandler发送到消息队列
final H mH = new H();
H类继承了Handler类,mH负责处理ApplicationThread发送到消息队列的消息,下面展示部分处理代码:
public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; ...
当ApplicationThread发送LAUNCH_ACTIVITY消息时,mH会执行上面的代码片段,其中最重要的是调用handleLaunchActivity(r, null),该方法调用performLaunchActivity启动对应的Activity;performLaunchActivity方法会使用ClassLoader加载Activity对应的class文件,然后调用activity.attach(),该方法为刚构造好的Activity设置内部变量并创建Window对象;之后performLaunchActivity方法调用mInstrumentation.callActivityOnCreate(activity, r.state),callActivityOnCreate方法内部调用activity的onCreate方法,activity的生命周期由此开始。
ActivityThread.performLaunchActivity()
ClassLoader加载Activity类,并实例化Activity对象
调用Activity.attach()方法为Activity对象创建Window对象,绑定WindowManager,Fragment等
调用Activity.performCreate方法,performCreate方法调用onCreate
android.os.Looper
用于为线程绑定一个消息队列,并且循环等待,当有消息时,唤起线程处理消息。主线程会默认创建一个Looper对象,其他线程需要调用Looper.prepare()方法为当前线程创建一个消息队列。Looper.prepare(); // 为当前线程创建一个Looper对象 Looper.getMainLooper(); // 返回当前应用主线程的Looper对象 Looper.myLooper(); // 返回当前线程的Looper对象 Looper.loop(); // 从消息队列中获取Message,并执行msg.target.dispatchMessage(msg),msg.target其实是绑定到消息队列的Handler
android.os.Handler
Handler对象和某线程的消息队列绑定起来,提供向消息队列中发送和接收Message的方法,当向消息队列发送Runnable时,Runnable会被封装进一个Message。Handler通过与线程绑定的消息队列实现两个线程之间的异步通信。其包括以下几个重要的方法:public Handler() { this(null, false); }
Handler()为默认构造方法,使用该构造函数要求当前线程拥有消息队列,handler会和该线程的消息队列绑定起来;该方法内部调用另一个构造方法,其源代码如下所示:
public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); // 获取该线程的Looper对象 if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; //获取该线程的消息队列 mCallback = callback; // 给回调对象赋值 mAsynchronous = async; }
其中第一个参数为一个回调对象,如果回调对象不为null,则会在dispatchMessage方法中被调用;
public void dispatchMessage(Message msg) { if (msg.callback != null) { // msg.callback为Runnable对象 handleCallback(msg); // msg.callback.run(); } else { if (mCallback != null) { //该Handler注册有回调对象,则调用该回调对象中的handleMessage方法 if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); // 默认该方法为空,重写的处理逻辑就包含在该方法中 } }
相关文章推荐
- 一个好的网站,应该用什么样的空间or服务器?建站基础知识普及
- Linux逻辑卷管理(LVM)详细教程
- Linux SVN服务器做定时增量备份脚本
- linux0.12之内核代码signal.c说明
- HBase 常用Shell命令
- 在Ubuntu 14.04 LTS系统中设置Apache虚拟主机
- openoffice转换过程中遇到繁体字文档转换失败的问题
- openoffice转换过程中遇到繁体字文档转换失败的问题
- docker高级应用之动态绑定卷组
- 惊魂web应用宕机记一次网站的紧急恢复
- 只读的PropertyGrid
- php获取从百度、谷歌等搜索引擎进入网站关键词的方法
- popoverController使用注意--转
- linux shell 数学运算
- opencv cvResizeWindow cvMoveWindow cvNamedWindow
- Zabbix分布式监控
- linux 内核代码的offsetof()宏
- linux/centos下安装nginx(rpm安装和源码安装)详细步骤
- IOPS和Throughput
- Linux——信号掩码(signal mask)