前言:
Android是支持多线程的,通常应用程序中与用户相关的UI事件都是运行在主线程中,比如点击屏幕、按钮等,为了保持主线程顺畅相应用户事件不被阻塞就需要把耗时的操作(主要是联网、操作大文件等)放到子线程中,这个时候你可能会想到Handler(当然还你可以用其他的比如:异步任务,,这个以后再讲),但是Handler又是怎么和Thread联系起来的呢?这个咱们来看一下Android主线程是怎么创建的。
ActivityThread:
在ActivityThread.java中有一个main()函数,这个函数就是在一个应用启动的入口,调用关系是:ActivityManagerService.java中的startProcessLocked函数调用如下代码:
前言:
之前的文章写的都是关于Bitmap和内存的优化技术,这一篇文章给大家谈谈Handler。
Handler是Android系统中比较重要的一个知识,在Android多线程面试经常会被问到,在实际项目中的确也经常用到。当然也比较复杂,知识比较多,牵扯到的类有Thread、Looper、Message、MessageQueue。
Android是支持多线程的,通常应用程序中与用户相关的UI事件都是运行在主线程中,比如点击屏幕、按钮等,为了保持主线程顺畅相应用户事件不被阻塞就需要把耗时的操作(主要是联网、操作大文件等)放到子线程中,这个时候你可能会想到Handler(当然还你可以用其他的比如:异步任务,,这个以后再讲),但是Handler又是怎么和Thread联系起来的呢?这个咱们来看一下Android主线程是怎么创建的。
ActivityThread:
在ActivityThread.java中有一个main()函数,这个函数就是在一个应用启动的入口,调用关系是:ActivityManagerService.java中的startProcessLocked函数调用如下代码:
// Start the process.? It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
? ? ? ? ? ? ? ? ? ? app.processName, uid, uid, gids, debugFlags,
? ? ? ? ? ? ? ? ? ? app.info.targetSdkVersion, null);
Process.start又做了如下的操作,只看方法注释就行,现在不需要知道具体做了什么:
/**
? ? * Start a new process.
? ? *
? ? *
If processes are enabled, a new process is created and the
? ? * static main() function of a processClass is executed there.
? ? * The process will continue running after this function returns.
? ? *
? ? *
If processes are not enabled, a new thread in the caller's
? ? * process is created and main() of processClass called there.
? ? *
? ? *
The niceName parameter, if not an empty string, is a custom name to
? ? * give to the process instead of using processClass.? This allows you to
? ? * make easily identifyable processes even if you are using the same base
? ? * processClass to start them.
? ? *
? ? * @param processClass The class to use as the process's main entry
? ? *? ? ? ? ? ? ? ? ? ? point.
? ? * @param niceName A more readable name to use for the process.
? ? * @param uid The user-id under which the process will run.
? ? * @param gid The group-id under which the process will run.
? ? * @param gids Additional group-ids associated with the process.
? ? * @param debugFlags Additional flags.
? ? * @param targetSdkVersion The target SDK version for the app.
? ? * @param zygoteArgs Additional arguments to supply to the zygote process.
? ? *
? ? * @return An object that describes the result of the attempt to start the process.
? ? * @throws RuntimeException on fatal start failure
? ? *
? ? * {@hide}
? ? */
? ? public static final ProcessStartResult start(final String processClass,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? final String niceName,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int uid, int gid, int[] gids,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int debugFlags, int targetSdkVersion,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String[] zygoteArgs) {
? ? ? ? try {
? ? ? ? ? ? return startViaZygote(processClass, niceName, uid, gid, gids,
? ? ? ? ? ? ? ? ? ? debugFlags, targetSdkVersion, zygoteArgs);
? ? ? ? } catch (ZygoteStartFailedEx ex) {
? ? ? ? ? ? Log.e(LOG_TAG,
? ? ? ? ? ? ? ? ? ? "Starting VM process through Zygote failed");
? ? ? ? ? ? throw new RuntimeException(
? ? ? ? ? ? ? ? ? ? "Starting VM process through Zygote failed", ex);
? ? ? ? }
? ? }
通过注释也能看到上面的函数会找到ActivityThread的main函数并且执行。main函数中创建了Looper,Looper的作用就是利用线程创建一个消息处理队列,并且维护这个消息队列:
?public static void main(String[] args) {
? ? ? ? Looper.prepareMainLooper();//创建Looper
? ? ? ? if (sMainThreadHandler == null) {
? ? ? ?