内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

深入淺析Android中的AsyncTask

這篇文章給大家介紹深入淺析Android中的AsyncTask,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

10多年的延壽網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整延壽建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“延壽網(wǎng)站設(shè)計(jì)”,“延壽網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

1、Asynctask簡(jiǎn)介

1.1 使用方法簡(jiǎn)介

Asynctask作為Android的基礎(chǔ)之一,怎么使用就不多講解了,網(wǎng)上到處都是教程,建議查看Android官方API文檔:https://developer.android.google.cn/reference/android/os/AsyncTask.html

這里只實(shí)現(xiàn)一個(gè)小Demo程序,供大家賞玩:

界面:

深入淺析Android中的AsyncTask

這個(gè)程序其實(shí)特別簡(jiǎn)單,就是兩個(gè)按鈕,點(diǎn)擊分別用來測(cè)試AysncTask和Handler兩種模式的實(shí)現(xiàn),點(diǎn)擊后會(huì)有相應(yīng)的Log提示。

功能簡(jiǎn)介:

Asynctask的實(shí)現(xiàn):

private class IAsyncTask extends AsyncTask<String, Integer, String> {
 protected String doInBackground(String... args1) {
 Log.i(TAG, "doInBackground in:" + args1[0]);
 int times = 10;
 for (int i = 0; i < times; i++) {
 publishProgress(i);//提交之后,會(huì)執(zhí)行onProcessUpdate方法
 }
 Log.i(TAG, "doInBackground out");
 return "over";
 }
 /**
 * 在調(diào)用cancel方法后會(huì)執(zhí)行到這里
 */
 protected void onCancelled() {
 Log.i(TAG, "onCancelled");
 }
 /**
 * 在doInbackground之后執(zhí)行
 */
 protected void onPostExecute(String args3) {
 Log.i(TAG, "onPostExecute:" + args3);
 }
 /**
 * 在doInBackground之前執(zhí)行
 */
 @Override
 protected void onPreExecute() {
 Log.i(TAG, "onPreExecute");
 }
 /**
 * 特別贊一下這個(gè)多次參數(shù)的方法,特別方便
 * @param args2
 */
 @Override
 protected void onProgressUpdate(Integer... args2) {
 Log.i(TAG, "onProgressUpdate:" + args2[0]);
 }
 }

點(diǎn)擊第一個(gè)按鈕后會(huì)執(zhí)行這里,點(diǎn)擊按鈕的寫法如下:

mBtnSyncTask.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 new IAsyncTask().execute("yanlog test");
 }
 });

執(zhí)行結(jié)果的Log如下:

02-19 21:55:12.179 10824-11010/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground in:yanlog test//doInbackground是在10824進(jìn)程,11010線程中執(zhí)行
02-19 21:55:12.179 10824-11010/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground out 
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:0//剩下的都是在10824線程中執(zhí)行,Android特別好的是,主線程的線程號(hào)跟進(jìn)程號(hào)是一致的
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:1
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:2
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:3
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:4
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:5
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:6
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:7
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:8
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onProgressUpdate:9
02-19 21:55:12.184 10824-10824/com.plbear.asynctasktest I/AsyncTaskTest: onPostExecute:over

Handler+Message實(shí)現(xiàn):

 主要代碼如下:

 private class IHandler extends Handler{
 @Override
 public void handleMessage(Message msg){
 switch(msg.what){
 case 1:
  Log.e(TAG,"handler:"+msg.obj);
  break;
 default:
  break;
 }
 }
 }

其中,調(diào)用地方如下:

mBtnHandlerTest.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 final Handler handler = new IHandler();
 new Thread(new Runnable() {
  @Override
  public void run() {
  for (int i = 0; i < 10; i++) {
  Message msg = new Message();
  msg.what = 1;
  msg.obj = new Integer(i);
  Log.e(TAG, "post message:" + i);
  handler.sendMessage(msg);
  }
  }
 }).start();
 }
 });

可以看到Log打印結(jié)果如下:

02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:0 //可以看到提交是在9319號(hào)子進(jìn)程中提交
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:1
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:2
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:3
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:4
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:5
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:6
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:7
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:8
02-19 22:25:17.689 9234-9319/com.plbear.asynctasktest E/AsyncTaskTest: post message:9
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:0 //可以看到提交完是在9234主線程中執(zhí)行。
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:1
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:2
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:3
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:4
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:5
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:6
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:7
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:8
02-19 22:25:17.692 9234-9234/com.plbear.asynctasktest E/AsyncTaskTest: handler:9

以上,簡(jiǎn)單梳理了下怎么實(shí)現(xiàn),不贅言。

1.2 Android 內(nèi)部源碼實(shí)現(xiàn)

關(guān)于Handler+Message+Message Queue+Looper的實(shí)現(xiàn)就不介紹了,老生常談了。所以下面主要看一下AsyncTask的源碼實(shí)現(xiàn):

AsyncTask的核心方法應(yīng)該是

public final AsyncTask<Params, Progress, Result> execute(Params... params)

那我們就看下當(dāng)調(diào)用了execute方法后,都發(fā)生了什么,下面是執(zhí)行的序列圖。

深入淺析Android中的AsyncTask

我知道我畫的不夠標(biāo)準(zhǔn)了,湊合著看吧。下面關(guān)于這個(gè)圖的一些說明。

  • 在第4步,execute的時(shí)候,這個(gè)時(shí)候可以看到,doInBackground已經(jīng)轉(zhuǎn)到子線程中執(zhí)行了,這個(gè)是很關(guān)鍵的一個(gè)點(diǎn),我特意用了一個(gè)異步處理的箭頭標(biāo)注了。
  • 在第9步,當(dāng)doInbackground執(zhí)行完,執(zhí)行到finish方法的時(shí)候,由通過sendMessage的方法回到了主線程中了,所以后面的onPostExecute和onCanceled都是在主線程中執(zhí)行的。

嗯,就這么多吧。關(guān)于AsyncTask的源碼我上傳到github中了,大家對(duì)照著源碼看會(huì)更清楚一點(diǎn)。

https://github.com/YanYoJun/AndroidSource/blob/master/AsyncTask.java

關(guān)于AsyncTask的源碼分析,還有一篇博客寫的很好,請(qǐng)參看:

https://www.jb51.net/article/81939.htm

備注:

源碼里面還有三個(gè)地方值得深究下,分別是:

  • FutureTask值得看下,回頭寫了博客我把鏈接貼在這里
  • AsyncTask中的SerialExecutor類寫的太漂亮了,回頭單獨(dú)寫一個(gè)博客欣賞下。
  • 關(guān)于上面的ThreadPollExecutor我其實(shí)沒有研究。。。回頭寫個(gè)博客研究下。

2、優(yōu)點(diǎn)

簡(jiǎn)單,快捷

這個(gè)說法就是近乎于扯淡吧,主要還是看使用習(xí)慣,我就挺喜歡用Handler的。

但是Android定義了這個(gè)東西,可以看到各種消息封裝的還是很不錯(cuò)的,很規(guī)范。大家可以按照這個(gè)“優(yōu)美的框架”來寫,代碼不會(huì)太出格。

3、缺點(diǎn)

3.1  AsyncTask實(shí)際上后臺(tái)線程之后一個(gè)?。?!

今天仔細(xì)研究了下源碼,發(fā)現(xiàn)網(wǎng)上寫的大部分是錯(cuò)的,AsyncTask的真正的后臺(tái)線程只有一個(gè)??!不信,看下面的代碼:

我們首先定義一個(gè)IAsyncTAsk,其中的doInBackground方法這么寫:

private class IAsyncTask extends AsyncTask<String, Integer, String> {
 protected String doInBackground(String... args1) {
/* Log.i(TAG, "doInBackground in:" + args1[0]);
 int times = 10;
 for (int i = 0; i < times; i++) {
 publishProgress(i);//提交之后,會(huì)執(zhí)行onProcessUpdate方法
 }
 Log.i(TAG, "doInBackground out");*/
 Log.i(TAG, "doInBackground in thread:" + args1[0]);
 try {
 int times = 4;
 for (int i = 0; i < times; i++) {
  Log.i(TAG, "thread alive:" + i + " for times"+args1[0]); //這個(gè)doInBackground就打印一個(gè)Log,然后sleep 20 毫秒
  Thread.sleep(20);
 }
 } catch (Exception e) {
 }
 return "over";
 }

調(diào)用的地方這么寫:

 int N = 5;
 for (int i = 0; i < N; i++) {
  Log.d(TAG,"asyncTask post Task:"+i);
  new IAsyncTask().execute("asyncTask times:"+i); //點(diǎn)擊Button后,在onClick方法中建立5個(gè)后臺(tái)子線程。
 }

我們來看打印結(jié)果:

02-20 21:48:08.206 14812-14812/com.plbear.asynctasktest D/AsyncTaskTest: asyncTask post Task:0 //在主線程中進(jìn)行提交操作
02-20 21:48:08.211 14812-14812/com.plbear.asynctasktest D/AsyncTaskTest: asyncTask post Task:1
02-20 21:48:08.211 14812-14812/com.plbear.asynctasktest D/AsyncTaskTest: asyncTask post Task:2
02-20 21:48:08.211 14812-14812/com.plbear.asynctasktest D/AsyncTaskTest: asyncTask post Task:3
02-20 21:48:08.211 14812-14812/com.plbear.asynctasktest D/AsyncTaskTest: asyncTask post Task:4
02-20 21:48:08.212 14812-18067/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground in thread:asyncTask times:0 //可以看到,雖然系統(tǒng)開起了18067、18068、
02-20 21:48:08.212 14812-18067/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:0 for timesasyncTask times:0//18069,18070這幾個(gè)子線程,但是這幾個(gè)子線程
02-20 21:48:08.232 14812-18067/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:1 for timesasyncTask times:0 //是串行執(zhí)行的!??!震驚了有沒有?。。?
02-20 21:48:08.253 14812-18067/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:2 for timesasyncTask times:0 //這不是巧合,試了好幾次都是這樣!!
02-20 21:48:08.273 14812-18067/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:3 for timesasyncTask times:0
02-20 21:48:08.294 14812-18068/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground in thread:asyncTask times:1
02-20 21:48:08.294 14812-18068/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:0 for timesasyncTask times:1
02-20 21:48:08.315 14812-18068/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:1 for timesasyncTask times:1
02-20 21:48:08.335 14812-18068/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:2 for timesasyncTask times:1
02-20 21:48:08.356 14812-18068/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:3 for timesasyncTask times:1
02-20 21:48:08.377 14812-18069/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground in thread:asyncTask times:2
02-20 21:48:08.377 14812-18069/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:0 for timesasyncTask times:2
02-20 21:48:08.397 14812-18069/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:1 for timesasyncTask times:2
02-20 21:48:08.417 14812-18069/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:2 for timesasyncTask times:2
02-20 21:48:08.438 14812-18069/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:3 for timesasyncTask times:2
02-20 21:48:08.462 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground in thread:asyncTask times:3
02-20 21:48:08.462 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:0 for timesasyncTask times:3
02-20 21:48:08.483 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:1 for timesasyncTask times:3
02-20 21:48:08.504 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:2 for timesasyncTask times:3
02-20 21:48:08.524 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:3 for timesasyncTask times:3
02-20 21:48:08.545 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: doInBackground in thread:asyncTask times:4
02-20 21:48:08.545 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:0 for timesasyncTask times:4
02-20 21:48:08.565 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:1 for timesasyncTask times:4
02-20 21:48:08.585 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:2 for timesasyncTask times:4
02-20 21:48:08.606 14812-18070/com.plbear.asynctasktest I/AsyncTaskTest: thread alive:3 for timesasyncTask times:4

你本來希望系統(tǒng)應(yīng)該這么執(zhí)行

深入淺析Android中的AsyncTask

但是實(shí)際上系統(tǒng)是這么執(zhí)行的:

深入淺析Android中的AsyncTask

那么從源碼看下為啥會(huì)這樣吧。

AsyncTask中默認(rèn)的Exector是這個(gè)private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;看下SERIAL_EXECUTOR是這么定義的

public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); //這是一個(gè)串行處理的Executor
.........................
 private static class SerialExecutor implements Executor {
 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
 Runnable mActive;
 public synchronized void execute(final Runnable r) {
 mTasks.offer(new Runnable() { //先把要執(zhí)行的子線程統(tǒng)一丟到mTasks隊(duì)列中,這其中封裝一遍Runnable
 public void run() {
  try {
  r.run();
  } finally {
  scheduleNext(); //當(dāng)前面一個(gè)子線程處理完,開始處理下一個(gè)
  }
 }
 });
 if (mActive == null) {
 scheduleNext();
 }
 }
 protected synchronized void scheduleNext() { //依次從隊(duì)列中取下一個(gè)元素,串行執(zhí)行
 if ((mActive = mTasks.poll()) != null) {
 THREAD_POOL_EXECUTOR.execute(mActive); 
 }
 }
 }

呵呵,這下子明白了吧。

Google為什么要怎么實(shí)現(xiàn)我不得而知,估計(jì)有什么我沒有明白的好處在里面吧。那么有沒有辦法規(guī)避呢?

可以看到上面有一個(gè)THREAD_POOL_EXECUTOR,這個(gè)也是一個(gè)executor是這么定義的

static {
 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
 CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
 sPoolWorkQueue, sThreadFactory);
 threadPoolExecutor.allowCoreThreadTimeOut(true);
 THREAD_POOL_EXECUTOR = threadPoolExecutor;
 }

可以看到這個(gè)是允許一定數(shù)量的子線程并行處理的。

其中參數(shù)是這么定義的

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
 // We want at least 2 threads and at most 4 threads in the core pool,
 // preferring to have 1 less than the CPU count to avoid saturating
 // the CPU with background work
 private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
 private static final int KEEP_ALIVE_SECONDS = 30;

按照一般理解,允許同時(shí)運(yùn)行的CORE進(jìn)程是4個(gè),MAXIMUM_POOL_SIZE是17個(gè)。(注:這個(gè)數(shù)字是我用榮耀8手機(jī)跑出來的,其他手機(jī)可能會(huì)有不同)

而Android中的AsyncTask提供了一個(gè)方法:

 public static void setDefaultExecutor(Executor exec) {
 sDefaultExecutor = exec;
 }

所以規(guī)避方法是:通過這個(gè)方法可以設(shè)置默認(rèn)的Exector,但是這個(gè)方法是hide的,也就是Google的隱藏方法,估計(jì)需要用一下反射來處理。我偷個(gè)懶,不去實(shí)現(xiàn)了。

關(guān)于深入淺析Android中的AsyncTask就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

文章名稱:深入淺析Android中的AsyncTask
網(wǎng)頁(yè)鏈接:http://www.rwnh.cn/article38/jgpdsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、全網(wǎng)營(yíng)銷推廣、微信小程序微信公眾號(hào)、定制開發(fā)、品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)
宜君县| 西乡县| 济宁市| 剑河县| 中牟县| 江津市| 仁布县| 砚山县| 沙田区| 榆林市| 西丰县| 平泉县| 班玛县| 湖北省| 南华县| 三亚市| 黄山市| 华蓥市| 茌平县| 乌兰察布市| 茂名市| 深圳市| 雅安市| 广州市| 灵川县| 利津县| 定结县| 金湖县| 阿克陶县| 桂阳县| 舞阳县| 河源市| 荆门市| 朔州市| 恩平市| 张家川| 麻江县| 多伦县| 昔阳县| 方正县| 遂宁市|