第 3

5.ExecutorServie线程池

通过Executors的静态方法来创建,一般有三种:

1.单线程 :Executors.newSingleThreadExecutor();

2.固定数量线程 :Executors.newFixedThreadPool();

3.动态线程 :Executors.newCachedThreadPool();

这里我们用固定5个线程来应用,使用方法是创建ExecutorService对象,然后执行submit(r)可以发起一个Runnable对象。用线程池来管理的好处是,可以保证系统稳定运行,适用与有大量线程,高工作量的情景下使用,假如要展示1000张图片如果创建1000个线程去加载,保证系统会死掉。用线程池就可以避免这个问题,可以用5个线程轮流执行,5个一组,执行完的线程不直接回收而是等待下次执行,这样对系统的开销就可以减小不少。

private void loadImagesByExecutors(final String url,final int id){
         service.submit(new Runnable(){
             
             @Override
             public void run() {
                 // TODO Auto-generated method stub
                 Log.e("当前线程:", ""+Thread.currentThread().getName());
                 
                 try {
                     final Drawable drawable  = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
                     mainHandler.post(new Runnable(){

                         @Override
                         public void run() {//这将在主线程运行
                             // TODO Auto-generated method stub
                             ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
                         }
                     });
                     
                 } catch (MalformedURLException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 
             }
             
         });
         
     }

Log:


Android 线程池队列 android 线程池管理_Android 线程池队列

其实可能没有说清楚,第一种不算多线程。

1.loadImagesByHandler()是通过Handler.post()方法,构建两个Handler进行通信。

2.loadImagesByThread(),这个是直接new Thread()发起线程,在主线程的handler处理消息

3.loadImageByAsyncTask(),这个用的是异步任务,所有实现在它的内部结构里,可以在里头操作Ui.

4.loadImagesByExecutors()用的是线程池,使得线程可控,保证稳定运行。

其实常用的就是后三种,第二个用法灵活,简单,但不适宜大数量任务;第三个一般适用于单个任务,一次性任务;第四个一般用于大数量,高密度执行的使用情景,比如批量加载图片,批量下载文件等。

看一眼图吧:


Android 线程池队列 android 线程池管理_android_02



全部源码:

1 package com.bvin.exec;
   2 
   3 import java.io.IOException;
   4 import java.net.MalformedURLException;
   5 import java.net.URL;
   6 import java.util.concurrent.ExecutorService;
   7 import java.util.concurrent.Executors;
   8 
   9 import android.app.Activity;
 10 import android.graphics.drawable.Drawable;
 11 import android.os.AsyncTask;
 12 import android.os.Bundle;
 13 import android.os.Handler;
 14 import android.os.HandlerThread;
 15 import android.os.Message;
 16 import android.util.Log;
 17 import android.view.View;
 18 import android.widget.Button;
 19 import android.widget.ImageView;
 20 
 21 public class MainActivity extends Activity {
 22     /** Called when the activity is first created. */
 23     
 24     private Handler handler ;
 25     private Button bt;
 26     private Handler mainHandler = new Handler(){
 27 
 28         @Override
 29         public void handleMessage(Message msg) {
 30             // TODO Auto-generated method stub
 31             super.handleMessage(msg);
 32             if(msg.what == 2012){
 33                 //只要在主线程就可以处理ui 
 34                 ((ImageView)MainActivity.this.findViewById(msg.arg1)).setImageDrawable((Drawable)msg.obj);
 35             }
 36         }
 37         
 38         
 39     };
 40     
 41     private ExecutorService service = Executors.newFixedThreadPool(5);
 42     
 43     @Override
 44     public void onCreate(Bundle savedInstanceState) {
 45         super.onCreate(savedInstanceState);
 46         setContentView(R.layout.main);
 47         initViews();
 48         HandlerThread ht = new HandlerThread("down image thread");
 49         ht.start();
 50         handler = new Handler(ht.getLooper()){//如果有了looper那么这个handler就不可以处理ui了
 51 
 52             @Override
 53             public void handleMessage(Message msg) {
 54                 // TODO Auto-generated method stub
 55                 super.handleMessage(msg);
 56                 
 57                 
 58             }
 59             
 60         };
 61         
 62     }
 63     
 64     private void initViews(){
 65         
 66         bt = (Button)findViewById(R.id.bt);
 67         bt.setOnClickListener(new View.OnClickListener() {
 68             
 69             @Override
 70             public void onClick(View v) {
 71                 // TODO Auto-generated method stub
 72                 loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/23c1625aca99f02c50d8e510383a34e7.jpg",R.id.iv1);
 73                 loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/c4698d97ef6d10722c8e917733c7beb3.jpg",R.id.iv2);
 74                 loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/f332ffe433be2a3112be15f78bff5a40.jpg",R.id.iv3);
 75                 loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/6ff8a9c647a1e80bc602eeda48865d4c.jpg",R.id.iv4);
 76                 loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/f104d069f7443dca52a878d779392874.jpg",R.id.iv5);
 77             }
 78         });
 79     }
 80     
 81     private void loadImagesByHandler(final String url,final int id){//通过拥有looper的handler.post(runnable),新建线程
 82         
 83         
 84         handler.post(new Runnable(){//如果handler没有Looper那么它就不能构建新线程了
 85 
 86             @Override
 87             public void run() {
 88                 // TODO Auto-generated method stub
 89                 Log.e("当前线程:", ""+Thread.currentThread().getName());
 90                 Drawable drawable = null;
 91                 try {
 92                     drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
 93                 } catch (MalformedURLException e) {
 94                     // TODO Auto-generated catch block
 95                     e.printStackTrace();
 96                 } catch (IOException e) {
 97                     // TODO Auto-generated catch block
 98                     e.printStackTrace();
 99                 }
 100                 //SystemClock.sleep(2000);
 101                 //((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
 102                 Message msg = mainHandler.obtainMessage();
 103                 msg.what = 2012;
 104                 msg.arg1 = id;
 105                 msg.obj = drawable;
 106                 msg.sendToTarget();
 107             }
 108             
 109         });
 110         
 111         
 112     }
 113     
 114     private void loadImagesByThread(final String url,final int id){//通过Thread来new 出多个线程
 115         
 116         new Thread(new Runnable(){
 117 
 118             @Override
 119             public void run() {
 120                 // TODO Auto-generated method stub
 121                 Log.e("当前线程:", ""+Thread.currentThread().getName());
 122                 Drawable drawable = null;
 123                 try {
 124                     drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
 125                 } catch (MalformedURLException e) {
 126                     // TODO Auto-generated catch block
 127                     e.printStackTrace();
 128                 } catch (IOException e) {
 129                     // TODO Auto-generated catch block
 130                     e.printStackTrace();
 131                 }
 132                 Message msg = mainHandler.obtainMessage();
 133                 msg.what = 2012;
 134                 msg.arg1 = id;
 135                 msg.obj = drawable;
 136                 msg.sendToTarget();
 137                 
 138             }
 139             
 140         }).start();
 141     } 
 142 
 143     private void loadImageByAsyncTask(final String url,final int id){//构建异步任务,这样就不用handler来处理消息了
 144         DownloadTask task = new DownloadTask();
 145         task.execute(""+id,url);//AsyncTask不可重复执行
 146     }
 147     
 148     private void loadImagesByExecutors(final String url,final int id){
 149         service.submit(new Runnable(){
 150             
 151             @Override
 152             public void run() {
 153                 // TODO Auto-generated method stub
 154                 Log.e("当前线程:", ""+Thread.currentThread().getName());
 155                 
 156                 try {
 157                     final Drawable drawable  = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
 158                     mainHandler.post(new Runnable(){
 159 
 160                         @Override
 161                         public void run() {//这将在主线程运行
 162                             // TODO Auto-generated method stub
 163                             ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
 164                         }
 165                     });
 166                     
 167                 } catch (MalformedURLException e) {
 168                     // TODO Auto-generated catch block
 169                     e.printStackTrace();
 170                 } catch (IOException e) {
 171                     // TODO Auto-generated catch block
 172                     e.printStackTrace();
 173                 }
 174                 
 175             }
 176             
 177         });
 178         
 179     }
 180     
 181     class DownloadTask extends AsyncTask{
 182 
 183         int id;
 184         @Override
 185         protected Drawable doInBackground(String... params) {//params保存url和控件id两个数据
 186             // TODO Auto-generated method stub
 187             Log.e("当前线程:", ""+Thread.currentThread().getName());
 188             Drawable drawable = null;
 189             this.id = Integer.parseInt(params[0]);
 190             try {
 191                 drawable = Drawable.createFromStream(new URL(params[1]).openStream(), "image.gif");
 192             } catch (MalformedURLException e) {
 193                 // TODO Auto-generated catch block
 194                 e.printStackTrace();
 195             } catch (IOException e) {
 196                 // TODO Auto-generated catch block
 197                 e.printStackTrace();
 198             }
 199             
 200             return drawable;
 201         }
 202 
 203         @Override
 204         protected void onPostExecute(Drawable result) {
 205             // TODO Auto-generated method stub
 206             super.onPostExecute(result);
 207             ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(result);
 208         }
 209 
 210         @Override
 211         protected void onPreExecute() {
 212             // TODO Auto-generated method stub
 213             super.onPreExecute();
 214         }
 215 
 216         @Override
 217         protected void onProgressUpdate(Integer... values) {
 218             // TODO Auto-generated method stub
 219             super.onProgressUpdate(values);
 220         }
 221 
 222         
 223     }
 224 }