Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android線程模型和AsyncTask

Android線程模型和AsyncTask

編輯:關於Android編程

的線程模型:當一個 android 的應用運行後,就會有一個 UI 的 main 線程啟動 , 這是一個非常重要的線程,它負責把事件分派到相應的控件,其中就包括屏幕繪圖事件,它同樣是用戶與 android 控件 交互的線程。比如,當你在屏幕上的 EditText 上輸入文字, UI 線程會把這個事件分發給剛輸入文字的 EditText ,緊接會向事件隊列發送一個更新 ( invalidate )請求。 UI 線程會把這個請求移出事件隊列並通知 EditText 在屏幕上重新繪制自身。

這種單線線程模型就會使得 android 的應用程序性能低下, 如果在這個單線程裡執行一些耗時的操作, 比如訪問數據庫, 或是從網絡端下載圖片, 就會會阻塞整個用戶界面。 比如如下操作:

 1 Bitmap b =  loadImageFromNetwork();

 


EE
這個操作非常耗時, 在這種情況下你會發現 , 界面僵死在那裡並且 android 在系統 5 秒中後沒有反應,會顯示一個關閉或等待的錯誤。www.2cto.com

也許我們可以使用一個新的 Thread 來解決它

 1 new Thread(new Runnable() {   

2      public void run() {                          

3           Bitmap b = loadImageFromNetwork();     

4           mImageView.setImageBitmap( b );     

5      }   

6 }).start();

但這樣會發生一些很難察覺的錯誤, 因為我們知道 UI 線程不是線程安全的。當然有很多種方法來處理這個問題:

android 提供了幾種在其他線程中訪問 UI 線程的方法。

• Activity.runOnUiThread( Runnable )
• View.post( Runnable )
• View.postDelayed( Runnable, long )
• Hanlder

 1 new Thread( new Runnable() {     

2             public void run() {     

3                      final Bitmap b = loadImageFromNetwork();     

4                      mImageView.post( new Runnable() {     

5                      mImageView.setImageBitmap( b );     

6 });     

7           }     

8 }).start();

這種方法比較繁瑣,同時當你需要實現一些很復雜的操作並需要頻繁地更新UI 時這會變得更糟糕。為了解決這個問題,android 提供了一個工具類:AsyncTask ,它使創建需要與用戶界面交互的長時間運行的任務變得更簡單。

就拿加載網絡圖片舉個例子:

 01 ublic class CanvasImageTask extends AsyncTask<ImageView, Void, Bitmap>{ 

02         private ImageView gView ; 

03           

04     protected Bitmap doInBackground(ImageView... views) { 

05                 Bitmap bmp = null ; 

06                 ImageView view = views[0]; 

07             // 根據iconUrl獲取圖片並渲染,iconUrl的url放在了view的tag中。 

08             if (view.getTag() != null) { 

09                     try { 

10                        URL url = new URL(view.getTag().toString()); 

11                        HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 

12                        conn.setDoInput(true); 

13                        conn.connect(); 

14                        InputStream stream = conn.getInputStream(); 

15                        bmp = BitmapFactory.decodeStream(stream); 

16                        stream.close(); 

17                     } catch (Exception e) { 

18                                 Log.v("img", e.getMessage()); 

19                             return null; 

20                     } 

21             } 

22             this.gView = view; 

23             return bmp; 

24     } 

25     protected void onPostExecute(Bitmap bm) { 

26             if (bm != null) { 

27                     this.gView.setImageBitmap(bm); 

28                     this.gView = null ; 

29             } 

30     } 

31       

32 } 

33 在Activity中直接調用 

34 if(!img.isDrawingCacheEnabled() || !holder.image.getTag().equals(imgpath)){ 

35                 img.setImageResource(R.drawable.icon_app); 

36                 img.setTag(imgpath); 

37                 try{ 

38                     new CanvasImageTask().execute(img); 

39                     img.setDrawingCacheEnabled(true); 

40                 }catch (Exception e) { 

41                     Log.e("error", "RejectedExecutionException in content_img: " +  imgpath);
這樣圖片加載使用異步線程便不會進行堵塞發生錯誤,我們還可以使用 callback 在圖片加載完後進行回調


 01 public class CanvasImageTaskCall extends AsyncTask<ImageView, Void, Bitmap> implements Callback{ 

02     private ImageView gView ; 

03       

04     protected Bitmap doInBackground(ImageView... views) { 

05             Bitmap bmp = null ; 

06             ImageView view = views[0]; 

07             // 根據iconUrl獲取圖片並渲染,iconUrl的url放在了view的tag中。 

08             if (view.getTag() != null) { 

09                     try { 

10                        URL url = new URL(view.getTag().toString()); 

11                        HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 

12                        conn.setDoInput(true); 

13                        conn.connect(); 

14                        InputStream stream = conn.getInputStream(); 

15                        bmp = BitmapFactory.decodeStream(stream); 

16                        stream.close(); 

17                     } catch (Exception e) { 

18                             e.printStackTrace(); 

19                             Log.v("img", e.getMessage()); 

20                             Message msg = new Message(); 

21                             msg.what = 0; 

22                             handleMessage(msg); 

23                             return null; 

24                     } 

25             } 

26             this.gView = view; 

27             return bmp; 

28     } 

29     protected void onPostExecute(Bitmap bm) { 

30             if (bm != null) { 

31                 this.gView.setImageBitmap(bm); 

32                 this.gView.setTag(bm); 

33                 this.gView = null ; 

34                 Message msg = new Message(); 

35                 msg.what = 1; 

36                 handleMessage(msg); 

37             } 

38     } 

39     public boolean handleMessage(Message msg) { 

40         // TODO Auto-generated method stub 

41         return false; 

42     } 

43       

44 }
在 Activity 中直接調用


 01 new CanvasImageTaskCall(){ 

02                         @Override

03                         public boolean handleMessage(Message msg) { 

04                                 switch (msg.what) { 

05                                 case 0: 

06                                         Log.i("test", "圖片加載失敗"); 

07                                         break; 

08                                 case 1: 

09                                         Log.i("test", "圖片加載成功"); 

10                                         break; 

11                                 default: 

12                                         break; 

13                                 } 

14                                 saveButton.setTextColor(Color.WHITE); 

15                                 saveButton.setClickable(true); 

16                                 bitmap = (Bitmap) imageView.getTag(); 

17                                 return super.handleMessage(msg); 

18                         } 

19                 }.execute(img);

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved