日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Android的UI設(shè)計與后臺線程交互

在Android的UI設(shè)計方面我們講過“Android UI”設(shè)計官方教程。本文將討論Android應(yīng)用程序的線程模型以及如何使用線程來處理耗時較長的操作,而不是在主線程中執(zhí)行,保證用戶界面(UI)的流暢運(yùn)行。本文還將闡述一些用戶界面(UI)中與線程交互的API。

UI用戶界面線程

當(dāng)應(yīng)用程序啟動時,系統(tǒng)會為應(yīng)用程序創(chuàng)建一個主線程(main)或者叫UI線程,它負(fù)責(zé)分發(fā)事件到不同的組件,包括繪畫事件。完成你的應(yīng)用程序與Android UI組件交互。

例如,當(dāng)您觸摸屏幕上的一個按鈕時,UI線程會把觸摸事件分發(fā)到組件上,更改狀態(tài)并加入事件隊列,UI線程會分發(fā)請求和通知到各個組件,完成相應(yīng)的動作。

單線程模型的性能是非常差的,除非你的應(yīng)用程序相當(dāng)?shù)暮唵?,特別是當(dāng)所有的操作都在主線程中執(zhí)行,比如訪問網(wǎng)絡(luò)或數(shù)據(jù)庫之類的耗時操作將會導(dǎo)致用戶界面鎖定,所有的事件將不能分發(fā),應(yīng)用程序就像死了一樣,更嚴(yán)重的是當(dāng)超過5秒時,系統(tǒng)就會彈出“應(yīng)用程序無響應(yīng)”的對話框。

如果你想看看什么效果,可以寫一個簡單的應(yīng)用程序,在一個Button的OnClickListener中寫上Thread.sleep(2000),運(yùn)行程序你就會看到在應(yīng)用程序回到正常狀態(tài)前按鈕會保持按下狀態(tài)2秒,當(dāng)這種情況發(fā)生時,您就會感覺到應(yīng)用程序反映相當(dāng)?shù)穆?/p>

總之,我們需要保證主線程(UI線程)不被鎖住,如果有耗時的操作,我們需要把它放到一個單獨的后臺線程中執(zhí)行。

下面是一個點擊按鈕后下載一個圖片,同時顯示到界面的ImageView上的例子:

 
 
 
  1.  
  2.  
  3. public void onClick(View v) {  
  4.   new Thread(new Runnable() {  
  5.     public void run() {  
  6.       Bitmap b = loadImageFromNetwork();  
  7.       mImageView.setImageBitmap(b);  
  8.     }  
  9.   }).start();  
  10. }  

起初,上面的代碼似乎是一個很好的解決方案,因為它不會鎖住用戶界面線程。然面不幸的是,它違反了用戶界面單線程模型:Android的用戶界面工具包不是線程安全的,只能在UI線程中操作它,在上面的代碼中,你在一個工作線程中調(diào)用mImageView.setImageBitmap(b)時,將會發(fā)生意想不到的錯誤,這種錯誤是非常難跟蹤和調(diào)試的。

Android提供了幾種方法來從其他線程訪問UI線程。您可能已經(jīng)熟悉他們了,下面是一個較全面的列表:

 
 
 
  1.  
  2.  
  3. Activity.runOnUiThread(Runnable)  
  4. View.post(Runnable)  
  5. View.postDelayed(Runnable, long)  
  6. Handler  

您可以使用這些類和方法中的任何一種糾正前面的代碼示例:

 
 
 
  1. public void onClick(View v) {  
  2.   new Thread(new Runnable() {  
  3.     public void run() {  
  4.       final Bitmap b = loadImageFromNetwork();  
  5.       mImageView.post(new Runnable() {  
  6.         public void run() {  
  7.           mImageView.setImageBitmap(b);  
  8.         }  
  9.       });  
  10.     }  
  11.   }).start();  

不幸的是,這些類和方法也往往使你的代碼更復(fù)雜,更難以閱讀。更糟糕的是,它需要頻繁執(zhí)行復(fù)雜的操作界面更新。

為了解決這個問題,1.5和更高版本的Android平臺提供了一個實用類稱為AsyncTask,簡化了長時間運(yùn)行的任務(wù),需要與用戶界面的交互。
類似AsyncTask的一個類UserTask也可用于Android 1.0和1.1版本,它提供了完全相同的API,所有您需要做的是把它的源代碼復(fù)制到你的應(yīng)用程序中。

AsyncTask的目標(biāo)是要為你的線程提供管理服務(wù),我們前面的例子可以很容易的用AsyncTask來改寫:

 
 
 
  1. public void onClick(View v) {  
  2.   new DownloadImageTask().execute("http://www.ideasandroid.com/image.png");  
  3. }  
  4.    
  5. private class DownloadImageTask extends AsyncTask {  
  6.      protected Bitmap doInBackground(String... urls) {  
  7.          return loadImageFromNetwork(urls[0]);  
  8.      }  
  9.    
  10.      protected void onPostExecute(Bitmap result) {  
  11.          mImageView.setImageBitmap(result);  
  12.      }  
  13.  } 

正如你所看到的,我們必須通過繼承AsyncTask類來使用它,非常重要的一點是:AsyncTask必須在UI線程中實例化它,并且只能執(zhí)行一次。

以下是AsyncTask的簡要使用方法:

◆您可以指定三個參數(shù)類型,泛型參數(shù),進(jìn)度值(執(zhí)行過程中返回的值)和最終值(執(zhí)行完返回的值)。

◆該方法doInBackground()自動執(zhí)行工作線程(后臺線程)

◆onPreExecute(),onPostExecute()和onProgressUpdate()都是在UI線程調(diào)用

◆由doInBackground返回的值()發(fā)送到onPostExecute()

◆您可以在執(zhí)行doInBackground()時調(diào)用publishProgress()然后在UI組程中執(zhí)行onProgressUpdate()。

◆您可以從任何線程隨時取消任務(wù)

不管你是否使用AsyncTask,時刻牢記單一線程模型的兩條規(guī)則:

1、不要鎖住用戶界面。

2、確保只在UI線程中訪問Android用戶界面工具包中的組件。

AsyncTask只是可以讓你更容易地做這些事情。

本文非原創(chuàng)作品,為外文翻譯,如有不對的地方請指正??!

原文:http://www.ideasandroid.com/Android/sdk/docs/resources/articles/painless-threading.html

【編輯推薦】

  1. 多圖詳解 “Android UI”設(shè)計官方教程
  2. Android觸屏textview及l(fā)istview對比驗證
  3. 8步教你打開Android之門 NDK入門教程
  4. Android開發(fā):系統(tǒng)自動實現(xiàn)開機(jī)啟動
  5. Android入門學(xué)習(xí)總攻略

分享標(biāo)題:Android的UI設(shè)計與后臺線程交互
本文鏈接:http://www.dlmjj.cn/article/ccoeoig.html