首页 > 代码库 > 第一章、主线程与子线程
第一章、主线程与子线程
第一章、主线程与子线程
但我们打开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属性,我们将在下一章中介绍。
第一章、主线程与子线程