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

android 的線程模型和AsyncTask

編輯:關於Android編程

  android 的線程模型:當一個 android 的應用運行後,就會有一個 UI 的 main 線程啟動 , 這是一個非常重要的線程,它負責把事件分派到相應的控件,其中就包括屏幕繪圖事件,它同樣是用戶與 android 控件 交互的線程。比如,當你在屏幕上的 EditText 上輸入文字, UI 線程會把這個事件分發給剛輸入文字的 EditText ,緊接會向事件隊列發送一個更新 ( invalidate )請求。 UI 線程會把這個請求移出事件隊列並通知 EditText 在屏幕上重新繪制自身。
這種單線線程模型就會使得 android 的應用程序性能低下, 如果在這個單線程裡執行一些耗時的操作, 比如訪問數據庫, 或是從網絡端下載圖片, 就會會阻塞整個用戶界面。 比如如下操作:

[java] 
Bitmap b =  loadImageFromNetwork();   

Bitmap b =  loadImageFromNetwork();  這個操作非常耗時, 在這種情況下你會發現 , 界面僵死在那裡並且 android 在系統 5 秒中後沒有反應,會顯示一個關閉或等待的錯誤。

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

[java] 
new Thread(new Runnable() {   
     public void run() {                          
          Bitmap b = loadImageFromNetwork();     
          mImageView.setImageBitmap( b );     
     }   
}).start();  

new Thread(new Runnable() { 
     public void run() {                        
          Bitmap b = loadImageFromNetwork();   
          mImageView.setImageBitmap( b );   
     } 
}).start(); 但這樣會發生一些很難察覺的錯誤, 因為我們知道 UI 線程不是線程安全的。當然有很多種方法來處理這個問題:

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

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

[java]
new Thread( new Runnable() {     
            public void run() {     
                     final Bitmap b = loadImageFromNetwork();     
                     mImageView.post( new Runnable() {     
                     mImageView.setImageBitmap( b );     
});     
          }     
}).start(); 

new Thread( new Runnable() {   
            public void run() {   
                     final Bitmap b = loadImageFromNetwork();   
                     mImageView.post( new Runnable() {   
                     mImageView.setImageBitmap( b );   
});   
          }   
}).start();這種方法比較繁瑣,同時當你需要實現一些很復雜的操作並需要頻繁地更新UI 時這會變得更糟糕。為了解決這個問題,android 提供了一個工具類:AsyncTask ,它使創建需要與用戶界面交互的長時間運行的任務變得更簡單。

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

[java] 
ublic class CanvasImageTask extends AsyncTask<ImageView, Void, Bitmap>{ 
        private ImageView gView ; 
         
    protected Bitmap doInBackground(ImageView... views) { 
                Bitmap bmp = null ; 
                ImageView view = views[0]; 
            // 根據iconUrl獲取圖片並渲染,iconUrl的url放在了view的tag中。  
            if (view.getTag() != null) { 
                    try { 
                       URL url = new URL(view.getTag().toString()); 
                       HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
                       conn.setDoInput(true); 
                       conn.connect(); 
                       InputStream stream = conn.getInputStream(); 
                       bmp = BitmapFactory.decodeStream(stream); 
                       stream.close(); 
                    } catch (Exception e) { 
                                Log.v("img", e.getMessage()); 
                            return null; 
                    } 
            } 
            this.gView = view; 
            return bmp; 
    } 
    protected void onPostExecute(Bitmap bm) { 
            if (bm != null) { 
                    this.gView.setImageBitmap(bm); 
                    this.gView = null ; 
            } 
    } 
     

在Activity中直接調用 
if(!img.isDrawingCacheEnabled() || !holder.image.getTag().equals(imgpath)){ 
                img.setImageResource(R.drawable.icon_app); 
                img.setTag(imgpath); 
                try{ 
                    new CanvasImageTask().execute(img); 
                    img.setDrawingCacheEnabled(true); 
                }catch (Exception e) { 
                    Log.e("error", "RejectedExecutionException in content_img: " +  imgpath); 

ublic class CanvasImageTask extends AsyncTask<ImageView, Void, Bitmap>{
        private ImageView gView ;
       
    protected Bitmap doInBackground(ImageView... views) {
                Bitmap bmp = null ;
                ImageView view = views[0];
            // 根據iconUrl獲取圖片並渲染,iconUrl的url放在了view的tag中。
            if (view.getTag() != null) {
                    try {
                       URL url = new URL(view.getTag().toString());
                       HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                       conn.setDoInput(true);
                       conn.connect();
                       InputStream stream = conn.getInputStream();
                       bmp = BitmapFactory.decodeStream(stream);
                       stream.close();
                    } catch (Exception e) {
                                Log.v("img", e.getMessage());
                            return null;
                    }
            }
            this.gView = view;
            return bmp;
    }
    protected void onPostExecute(Bitmap bm) {
            if (bm != null) {
                    this.gView.setImageBitmap(bm);
                    this.gView = null ;
            }
    }
   
}
在Activity中直接調用
if(!img.isDrawingCacheEnabled() || !holder.image.getTag().equals(imgpath)){
                img.setImageResource(R.drawable.icon_app);
                img.setTag(imgpath);
                try{
                    new CanvasImageTask().execute(img);
                    img.setDrawingCacheEnabled(true);
                }catch (Exception e) {
                    Log.e("error", "RejectedExecutionException in content_img: " +  imgpath);這樣圖片加載使用異步線程便不會進行堵塞發生錯誤,我們還可以使用 callback 在圖片加載完後進行回調

[java] 
public class CanvasImageTaskCall extends AsyncTask<ImageView, Void, Bitmap> implements Callback{ 
    private ImageView gView ; 
     
    protected Bitmap doInBackground(ImageView... views) { 
            Bitmap bmp = null ; 
            ImageView view = views[0]; 
            // 根據iconUrl獲取圖片並渲染,iconUrl的url放在了view的tag中。  
            if (view.getTag() != null) { 
                    try { 
                       URL url = new URL(view.getTag().toString()); 
                       HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
                       conn.setDoInput(true); 
                       conn.connect(); 
                       InputStream stream = conn.getInputStream(); 
                       bmp = BitmapFactory.decodeStream(stream); 
                       stream.close(); 
                    } catch (Exception e) { 
                            e.printStackTrace(); 
                            Log.v("img", e.getMessage()); 
                            Message msg = new Message(); 
                            msg.what = 0; 
                            handleMessage(msg); 
                            return null; 
                    } 
            } 
            this.gView = view; 
            return bmp; 
    } 
    protected void onPostExecute(Bitmap bm) { 
            if (bm != null) { 
                this.gView.setImageBitmap(bm); 
                this.gView.setTag(bm); 
                this.gView = null ; 
                Message msg = new Message(); 
                msg.what = 1; 
                handleMessage(msg); 
            } 
    } 
    public boolean handleMessage(Message msg) { 
        // TODO Auto-generated method stub  
        return false; 
    } 
     

public class CanvasImageTaskCall extends AsyncTask<ImageView, Void, Bitmap> implements Callback{
    private ImageView gView ;
   
    protected Bitmap doInBackground(ImageView... views) {
            Bitmap bmp = null ;
            ImageView view = views[0];
            // 根據iconUrl獲取圖片並渲染,iconUrl的url放在了view的tag中。
            if (view.getTag() != null) {
                    try {
                       URL url = new URL(view.getTag().toString());
                       HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                       conn.setDoInput(true);
                       conn.connect();
                       InputStream stream = conn.getInputStream();
                       bmp = BitmapFactory.decodeStream(stream);
                       stream.close();
                    } catch (Exception e) {
                            e.printStackTrace();
                            Log.v("img", e.getMessage());
                            Message msg = new Message();
                            msg.what = 0;
                            handleMessage(msg);
                            return null;
                    }
            }
            this.gView = view;
            return bmp;
    }
    protected void onPostExecute(Bitmap bm) {
            if (bm != null) {
                this.gView.setImageBitmap(bm);
                this.gView.setTag(bm);
                this.gView = null ;
                Message msg = new Message();
                msg.what = 1;
                handleMessage(msg);
            }
    }
    public boolean handleMessage(Message msg) {
        // TODO Auto-generated method stub
        return false;
    }
   
}在 Activity 中直接調用

[java] 
new CanvasImageTaskCall(){ 
                        @Override 
                        public boolean handleMessage(Message msg) { 
                                switch (msg.what) { 
                                case 0: 
                                        Log.i("test", "圖片加載失敗"); 
                                        break; 
                                case 1: 
                                        Log.i("test", "圖片加載成功"); 
                                        break; 
                                default: 
                                        break; 
                                } 
                                saveButton.setTextColor(Color.WHITE); 
                                saveButton.setClickable(true); 
                                bitmap = (Bitmap) imageView.getTag(); 
                                return super.handleMessage(msg); 
                        } 
                }.execute(img); 

new CanvasImageTaskCall(){
                        @Override
                        public boolean handleMessage(Message msg) {
                                switch (msg.what) {
                                case 0:
                                        Log.i("test", "圖片加載失敗");
                                        break;
                                case 1:
                                        Log.i("test", "圖片加載成功");
                                        break;
                                default:
                                        break;
                                }
                                saveButton.setTextColor(Color.WHITE);
                                saveButton.setClickable(true);
                                bitmap = (Bitmap) imageView.getTag();
                                return super.handleMessage(msg);
                        }
                }.execute(img);

 

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