• 有关android UI 线程


    1. GUI线程框架

    常见的 Swing, SWT框架都是作为单线程子系统来实现的,实际上不仅限于在Java中, Qt、MacOS Cocoa以及其他的环境中的GUI框架都是单线程的。虽然很多人尝试过其他的方案但最终回到了单线程的事件模型,简单来看最主要的原因还在于多线程的GUI中更容易出现死锁的问题[1]。

    从android应用层来看,UI线程可以对应到系统中的ActivityThread,其中的main方法,建立主线程关联的 Looper 以及MessageQueue。不难看出它是应用层的入口点。

     1     public static void main(String[] args) {
     2         SamplingProfilerIntegration.start();
     3 
     4         // CloseGuard defaults to true and can be quite spammy.  We
     5         // disable it here, but selectively enable it later (via
     6         // StrictMode) on debug builds, but using DropBox, not logs.
     7         CloseGuard.setEnabled(false);
     8 
     9         Process.setArgV0("<pre-initialized>");
    10 
    11         Looper.prepareMainLooper();
    12         if (sMainThreadHandler == null) {
    13             sMainThreadHandler = new Handler();
    14         }
    15 
    16         ActivityThread thread = new ActivityThread();
    17         thread.attach(false);
    18 
    19         if (false) {
    20             Looper.myLooper().setMessageLogging(new
    21                     LogPrinter(Log.DEBUG, "ActivityThread"));
    22         }
    23 
    24         Looper.loop();
    25 
    26         throw new RuntimeException("Main thread loop unexpectedly exited");
    27     }

    2. ANR

    恶名远播的“Application Not Responding” 弹出框。由1中所述,单线程模型下的主线程如果做了其它大量复杂耗时的工作,无疑会对应用的性能造成极大影响。看到ANR实际上是系统发出警告了。在Activity生命周期方法里面的代码处理,BroadcastReceiver#onReceive() 的执行,同一进程级内的直接运行在主线程中的Service 在执行复杂后台任务时, 以及对IO的操作诸如数据库访问、文件读写等都需要考虑耗时的情况,必要时采用异步执行。

    除了手动构建新的Thread方式外,系统也提供了众多方便的工具,如 AsyncTaskHandlerThreadLoaderManager 等等。我们完全可以将主线程上的重负分离出来,构建更具有良好交互响应的应用。

    3. 多线程条件下的影响

    注意到多线程执行的环境下,自定义实现的Thread需要防止与主线程产生竞争的问题。系统底层线程(Linux 的POSIX threads,又称 Pthreads)在被调度执行时与线程自身的优先级有关了。而一般自定义实现的Thread优先级别与主线程相同,考虑到对CPU时间片的占用,我们可以降低这类工作线程的优先级:

    "Standard priority background threads. This gives your thread a slightly lower than normal priority, so that it will have less chance of impacting the responsiveness of the user interface."
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    

    对比可以看到 android.os.AsyncTask 中新增异步任务时的实现部分 :

     mWorker = new WorkerRunnable<Params, Result>() {
                public Result call() throws Exception {
                    mTaskInvoked.set(true);
    
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    return postResult(doInBackground(mParams));
                }
            };
    

    如果后台有工作线程频繁的执行操作时,在单核CPU的设备上对比可以发现,优先级的设置对主线程有比较明显的响应。

    引用:

    [1] 《Java并发编程实践》 P156

  • 相关阅读:
    unittest框架assert断言
    python logging 总结
    好文章推荐 数据库mysql
    python 日志模块 日志格式
    django admin 后台总结(转载)
    xpath解析html标签
    lua 排序table.sort()用法
    lua 随机数 math.random()和math.randomseed()用法
    三种方法获取 lua时间戳
    crontab调用python脚本新思路
  • 原文地址:https://www.cnblogs.com/raywalker/p/3172710.html
Copyright © 2020-2023  润新知