Android主线程的消息系统(Handler\Looper)

之前的文章写的都是关于Bitmap和内存的优化技术,这一篇文章给大家谈谈Handler。

Handler是Android系统中比较重要的一个知识,在Android多线程面试经常会被问到,在实际项目中的确也经常用到。当然也比较复杂,知识比较多,牵扯到的类有Thread、Looper、Message、MessageQueue。

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.
    *
    * <p>If processes are enabled, a new process is created and the
    * static main() function of a <var>processClass</var> is executed there.
    * The process will continue running after this function returns.
    *
    * <p>If processes are not enabled, a new thread in the caller's
    * process is created and main() of <var>processClass</var> called there.
    *
    * <p>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
    * <var>processClass</var> 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);
        }
    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/bea06878edc58d744cabe120d1c4c232.html