首页 > 代码库 > 第一章、主线程与子线程

第一章、主线程与子线程

第一章、主线程与子线程


但我们打开FBReader程序的一刻,代码会立即创建一个子线程。之后,主线程会负责在屏幕上显示一个进度条,而子线程则在后台开始读取epub文件。

    PS:进度条的样子如下图所示,不过由于加载速度很快,这进度条都是一闪而过的。这张图片是在单步调试的环境下截取的。

在这一章,我们将详细介绍,程序如何创建子线程,以及如何控制进度条的显示与消失。
本章涉及的核心类是UIUtil类。


FBReader默认首先进入的FBReader类,这是在AndroidManifes.xml设定的。

ZLAndroidActivity类中的onCreate方法

    FBReader类的onCreate方法会首先触发FBReader类的父类ZLAndroidActivity类中的onCreate方法。
      

    这个方法中进行了一系列的初始化工作:
    102行:设置程序为全屏
    107行:设置程序的界面,这个界面是ViewZLAndroidWidget类。我们会在第十章“epub文件处理 -- 显示”中详细分析这个类的onDraw方法。
    110行:调用ZLAndroidLibrary类的setActivity方法,为ZLAndroidLibrary类里面的myActivity变量赋了值(请大家记住这个方法,我们马上会用到这个变量)
    114行:调用FBReader类的createApplication方法,返回一个FBReaderApp类
    117行:调用FBReaderApp类的子类FBReaderApp中的initWindow方法,这个方法方法将负责建立子线程,并在主线程显示进度条

FBReaderApp类的initWindow方法、ZLAndroidApplicationWindow类wait方法

    FBReaderApp类的initWindow方法调用了ZLApplication类的wait方法。而ZLApplication类的wait方法又会最终调用ZLAndroidApplicationWindow类wait方法
    请记住initWindow方法中定义的Runnable类,这个类中的内容就是之后要在子线程中要运行的读取epub文件的代码。
    

    还记得刚才要大家记住的ZLAndroidLibrary类的setActivity方法吗?当时这个方法,给ZLAndroidLibrary类的myActivity变量赋了值。现在ZLAndroidLibrary类的wait方法会判断这个属性,如这个属性为null,就会直接在主线程中运行读取epub文件的代码(这样可能会造成主线程中的UI产生停滞);如果这个属性不为null,就会调用UIUtil类的wai方法,分两个线程处理程序

    

UIUtil类wait方法

    在UIUtil类中的wait方法中,我们可以看到代码新开了一个子线程(78行),子线程中运行的代码是ZLApplication类的FBReaderApp类的initWindow方法中定义的Runnable类中的内容。同时,主线程调用ProgressBar类的show方法显示了一个进度条(我们会在下一章中详细介绍如何获得进度条中要显示的字)。


关于进度条,有两个部分需要详细介绍一下:第一是如何让进度条消失,第二是如何获取进度条要显示的文字。

进度条的消失

    首先来介绍如何让ProgressBar消失。
    让进度条显示的方法很简单,只要调用ProgressDialog类的show方法即可。
    

    ourProgressHandler变量指向的Handler类中一旦收到子线程的“通知”就会让进度条消失

    

    这里要请大家注意一下,UIUtil类的wait方法考虑到了多重后台任务的情况下,进度条怎样显示与消失。多重后台任务的情况,肯定必须是所有任务都完成的情况下,才能让进度条消失,那么代码是如何实现的呢?

    代码首先在UIUtil类的wait方法中用ourTaskQueue属性保存所有的后台任务
    

    然后,在Handler类中判断ourTaskQueue中是否为空,为空时才让进度条消失

    

    同时,因为子线程和Handler类都在操作ourTaskQueue,必须使用wait方法和notify方法保证整个变量线程安全

    

进度条上要显示的文字

    接下来,介绍如何获取ProgressBar要显示的文字
    显示在进度条上的文字就是从资源文件里面读取出来的message变量。
    

    资源文件的位置在assets/resourses中application和zlibrary两个文件夹中。    

    

    这两个文件夹中存储了各种语言的版本,其中FBReader程序默认的是uk.xml,而代码最终会根据手机的语言设置,去显示zh.xml中的内容。

    

    我们要寻找的显示在ProgressBar中的文字就在application文件夹中zh.xml文件中dialog节点下的waitMesssage节点下的loadingBook节点的value属性。

    

    代码具体如何解析zh.xml文件,来获取指定节点下的value属性,我们将在下一章中介绍。

第一章、主线程与子线程