本篇漫笔将解说一下Android的多线程的常识,以及怎样经过AsyncTask机制来完结线程之间的通讯。
一、Android傍边的多线程
在Android傍边,当一个运用程序的组件发动的时分,而且没有其他的运用程序组件在运转时,Android体系就会为该运用程序组件拓荒一个新的线程来履行。默许的情况下,在一个相同Android运用程序傍边,其里边的组件都是运转在同一个线程里边的,这个线程咱们称之为Main线程。当咱们经过某个组件来发动另一个组件的时分,这个时分默许都是在同一个线程傍边完结的。当然,咱们能够自己来办理咱们的Android运用的线程,咱们能够依据咱们自己的需求来给运用程序创立额定的线程。
二、Main Thread 和 Worker Thread
在Android傍边,一般将线程分为两种,一种叫做Main Thread,除了Main Thread之外的线程都可称为Worker Thread。
当一个运用程序运转的时分,Android操作体系就会给该运用程序发动一个线程,这个线程便是咱们的Main Thread,这个线程十分的重要,它首要用来加载咱们的UI界面,完结体系和咱们用户之间的交互,并将交互后的成果又展现给咱们用户,所以Main Thread又被称为UI Thread。
Android体系默许不会给咱们的运用程序组件创立一个额定的线程,一切的这些组件默许都是在同一个线程中运转。但是,某些时分当咱们的运用程序需求完结一个耗时的操作的时分,例如拜访网络或者是对数据库进行查询时,此刻咱们的UI Thread就会被堵塞。例如,当咱们点击一个Button,然后期望其从网络中获取一些数据,假如此操作在UI Thread傍边完结的话,当咱们点击Button的时分,UI线程就会处于堵塞的状况,此刻,咱们的体系不会调度任何其它的事情,更糟糕的是,当咱们的整个现场假如堵塞时间超越5秒钟(官方是这样说的),这个时分就会呈现 ANR (Application Not Responding)的现象,此刻,运用程序会弹出一个框,让用户挑选是否退出该程序。关于Android开发来说,呈现ANR的现象是肯定不能被答应的。
别的,因为咱们的Android UI控件是线程不安全的,所以咱们不能在UI Thread之外的线程傍边对咱们的UI控件进行操作。因此在Android的多线程编程傍边,咱们有两条十分重要的准则必需求恪守:
– 肯定不能在UI Thread傍边进行耗时的操作,不能堵塞咱们的UI Thread
– 不能在UI Thread之外的线程傍边操作咱们的UI元素
三、怎样处理UI Thread 和 Worker Thread之间的通讯
既然在Android傍边有两条重要的准则要恪守,那么咱们或许就有疑问了?咱们既不能在主线程傍边处理耗时的操作,又不能在作业线程中来拜访咱们的UI控件,那么咱们比如从网络中要下载一张图片,又怎样能将其更新到UI控件上呢?这就联系到了咱们的主线程和作业线程之间的通讯问题了。在Android傍边,供给了两种办法来处理线程直接的通讯问题,一种是经过Handler的机制(这种办法在后面的漫笔中将具体介绍),还有一种便是今日要具体解说的 AsyncTask 机制。
四、AsyncTask
AsyncTask:异步使命,从字面上来说,便是在咱们的UI主线程运转的时分,异步的完结一些操作。AsyncTask答应咱们的履行一个异步的使命在后台。咱们能够将耗时的操作放在异步使命傍边来履行,并随时将使命履行的成果回来给咱们的UI线程来更新咱们的UI控件。经过AsyncTask咱们能够轻松的处理多线程之间的通讯问题。
怎样来了解AsyncTask呢?浅显一点来说,AsyncTask就相当于Android给咱们供给了一个多线程编程的一个结构,其介于Thread和Handler之间,咱们假如要界说一个AsyncTask,就需求界说一个类来承继AsyncTask这个笼统类,并完结其仅有的一个 doInBackgroud 笼统办法。要把握AsyncTask,咱们就必需求一个概念,总结起来便是: 3个泛型,4个过程。
3个泛型指的是什么呢?咱们来看看AsyncTask这个笼统类的界说,当咱们界说一个类来承继AsyncTask这个类的时分,咱们需求为其指定3个泛型参数:
– Params: 这个泛型指定的是咱们传递给异步使命履行时的参数的类型
– Progress: 这个泛型指定的是咱们的异步使命在履行的时分将履行的进展回来给UI线程的参数的类型
– Result: 这个泛型指定的异步使命履行完后回来给UI线程的成果的类型
咱们在界说一个类承继AsyncTask类的时分,必需求指定好这三个泛型的类型,假如都不指定的话,则都将其写成Void,例如:
4个过程:当咱们履行一个异步使命的时分,其需求依照下面的4个过程别离履行
– onPreExecute(): 这个办法是在履行异步使命之前的时分履行,而且是在UI Thread傍边履行的,一般咱们在这个办法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog
– doInBackground(Params… params): 在onPreExecute()办法履行完之后,会立刻履行这个办法,这个办法便是来处理异步使命的办法,Android操作体系会在后台的线程池傍边敞开一个worker thread来履行咱们的这个办法,所以这个办法是在worker thread傍边履行的,这个办法履行完之后就能够将咱们的履行成果发送给咱们的最终一个 onPostExecute 办法,在这个办法里,咱们能够从网络傍边获取数据等一些耗时的操作
– onProgressUpdate(Progess… values): 这个办法也是在UI Thread傍边履行的,咱们在异步使命履行的时分,有时分需求将履行的进展回来给咱们的UI界面,例如下载一张网络图片,咱们需求时间显现其下载的进展,就能够运用这个办法来更新咱们的进展。这个办法在调用之前,咱们需求在 doInBackground 办法中调用一个 publishProgress(Progress) 的办法来将咱们的进展时时间刻传递给 onProgressUpdate 办法来更新