UiThread DEMO

  1 import java.util.concurrent.ExecutorService;
  2 import java.util.concurrent.Executors;
  3 import android.app.Activity;
  4 import android.app.Dialog;
  5 import android.app.ProgressDialog;
  6 import android.content.Context;
  7 import android.os.Handler;
  8 import android.os.Looper;
  9 import android.os.Message;
 10 
 11 public class UiThread {
 12     private static Context mainContext;
 13     private static Handler mainHandler;
 14     private static ExecutorService pool;
 15     // 最大执行线程数量
 16     private static final int MAXTHREADCOUNT = 5;
 17 
 18     private Object obj;       // 运行时需要的obj
 19     private String flag = ""; // 防止null
 20     private long runDelayMillis;      // 运行前延迟
 21     private long callbackDelayMills;  // 回调前延时
 22     private Dialog dialog;
 23     private UIThreadEvent event;
 24     private UIpublisher publisher;
 25     private Object back;
 26     private Context context;
 27 
 28     public interface UIThreadEvent {
 29         public Object runInThread(String flag, Object obj, Publisher publisher);
 30 
 31         public void runInUi(String flag, Object obj, boolean ispublish,
 32                 float progress);
 33     }
 34 
 35     public interface Publisher {
 36         public void publishProgress(float progress);
 37 
 38         public void publishObject(Object object);
 39     }
 40 
 41     public class PublishData {
 42         Object obj;
 43         float progress;
 44         UiThread uithread;
 45     }
 46 
 47     public static UiThread init(Context content) {
 48         return new UiThread((Activity) content);
 49     }
 50 
 51     public class UIpublisher implements Publisher {
 52         public UiThread uithread;
 53 
 54         public UIpublisher(UiThread uithread) {
 55             this.uithread = uithread;
 56         }
 57 
 58         @Override
 59         public void publishProgress(float progress) {
 60             PublishData data = new PublishData();
 61             data.uithread = uithread;
 62             data.progress = progress;
 63             data.obj = null;
 64 
 65             Message msg = Message.obtain();
 66             msg.obj = data;
 67             mainHandler.sendMessage(msg);
 68         }
 69 
 70         @Override
 71         public void publishObject(Object object) {
 72             PublishData data = new PublishData();
 73             data.uithread = uithread;
 74             data.progress = -1;
 75             data.obj = object;
 76 
 77             Message msg = Message.obtain();
 78             msg.obj = data;
 79             mainHandler.sendMessage(msg);
 80         }
 81 
 82     }
 83 
 84     public UiThread(Activity activity) {
 85         this.context = activity;
 86         if (mainHandler == null || mainContext != context) {
 87             mainContext = context;
 88 
 89             if (Looper.myLooper() != Looper.getMainLooper()) {
 90                 throw new InternalError("uiThread cannot init from thread!");
 91             }
 92 
 93             mainHandler = new Handler() {
 94                 @Override
 95                 public void handleMessage(Message msg) {
 96                     if (msg == null)
 97                         return;
 98 
 99                     Object obj = msg.obj;
100                     if (obj instanceof UiThread) {
101                         UiThread data = (UiThread) obj;
102                         // 如果是activity,finish后就不回调mainthread
103                         if (context instanceof Activity) {
104                             if (((Activity) data.context).isFinishing()) {
105                                 return;
106                             }
107                         }
108 
109                         if (data.dialog != null) {
110                             // 关闭加载窗
111                             data.dialog.dismiss();
112                         }
113                         data.event.runInUi(data.flag, data.back, false, -1);
114 
115                         // 清理
116                         data.dialog = null;
117                         data.event = null;
118                         data.publisher = null;
119                         data = null;
120                     } else if (obj instanceof PublishData) {
121                         PublishData data = (PublishData) obj;
122 
123                         if (data.uithread.dialog instanceof ProgressDialog) {
124                             // 如果设置显示了ProgressDialog,自动更新dialog的进度
125                             if (data.uithread.dialog.isShowing()
126                                     && data.progress > 0 && data.progress < 100) {
127                                 ((ProgressDialog) data.uithread.dialog)
128                                         .setMessage(data.progress + "%");
129                             }
130                         }
131 
132                         data.uithread.event.runInUi(data.uithread.flag,
133                                 data.obj, true, data.progress);
134 
135                         // 清理
136                         data.uithread = null;
137                         data.obj = null;
138                         data = null;
139                     }
140                     msg.obj = null;
141                 }
142             };
143         }
144         if (pool == null) {
145             pool = Executors.newFixedThreadPool(MAXTHREADCOUNT); // 固定线程池
146         }
147     }
148 
149     public UiThread setFlag(String flag) {
150         this.flag = flag;
151         return this;
152     }
153 
154     public UiThread setObject(Object obj) {
155         this.obj = obj;
156         return this;
157     }
158 
159     public UiThread showDialog(Dialog dialog) {
160         if (this.dialog != null) {
161             if (this.dialog.isShowing()) {
162                 this.dialog.dismiss();
163             }
164         }
165 
166         this.dialog = dialog;
167         return this;
168     }
169 
170     public UiThread showDialog(String tip, boolean canCancel) {
171         if (dialog != null) {
172             if (dialog.isShowing()) {
173                 dialog.dismiss();
174             }
175         }
176 
177         if (tip == null) {
178             dialog = ProgressDialog.show(context, null, "加载中", true, canCancel,
179                     null);
180         } else {
181             dialog = ProgressDialog.show(context, null, tip, true, canCancel,
182                     null);
183         }
184         return this;
185     }
186 
187     public UiThread setRunDelay(long delayMillis) {
188         this.runDelayMillis = delayMillis;
189         return this;
190     }
191 
192     public UiThread setCallBackDelay(long delayMillis) {
193         this.callbackDelayMills = delayMillis;
194         return this;
195     }
196 
197     public void start(UIThreadEvent event) {
198         this.event = event;
199         publisher = new UIpublisher(this);
200 
201         if (dialog != null) {
202             dialog.show();
203         }
204 
205         pool.execute(new Runnable() {
206             @Override
207             public void run() {
208                 try {
209                     Thread.sleep(runDelayMillis);
210                 } catch (Exception e) {
211                     e.printStackTrace();
212                 }
213                 UiThread.this.back = UiThread.this.event.runInThread(flag, obj,
214                         publisher);
215                 Message msg = Message.obtain();
216                 msg.obj = UiThread.this;
217                 mainHandler.sendMessageDelayed(msg, callbackDelayMills);
218             }
219         });
220     }
221 }
  1 import java.io.File;
  2 import java.io.FileOutputStream;
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.net.HttpURLConnection;
  6 import java.net.MalformedURLException;
  7 import java.net.URL;
  8 
  9 import org.apache.http.HttpEntity;
 10 import org.apache.http.HttpResponse;
 11 import org.apache.http.client.HttpClient;
 12 import org.apache.http.client.methods.HttpGet;
 13 import org.apache.http.impl.client.DefaultHttpClient;
 14 import org.apache.http.util.EntityUtils;
 15 
 16 import android.app.Activity;
 17 import android.graphics.Bitmap;
 18 import android.graphics.BitmapFactory;
 19 import android.os.Bundle;
 20 import android.os.Environment;
 21 import android.os.Message;
 22 import android.view.View;
 23 import android.view.View.OnClickListener;
 24 import android.widget.ImageView;
 25 import android.widget.TextView;
 26 
 27 import com.yunxun.tool.UiThread;
 28 import com.yunxun.tool.UiThread.Publisher;
 29 import com.yunxun.tool.UiThread.UIThreadEvent;
 30 
 31 public class MainActivity extends Activity implements OnClickListener,
 32         UIThreadEvent {
 33     TextView tv;
 34     ImageView img;
 35 
 36     @Override
 37     protected void onCreate(Bundle savedInstanceState) {
 38         super.onCreate(savedInstanceState);
 39         setContentView(R.layout.activity_main);
 40         tv = (TextView) findViewById(R.id.tv);
 41         img = (ImageView) findViewById(R.id.img);
 42         findViewById(R.id.btn_get).setOnClickListener(this);
 43         findViewById(R.id.btn_image).setOnClickListener(this);
 44         findViewById(R.id.btn_nor).setOnClickListener(this);
 45         findViewById(R.id.btn_down).setOnClickListener(this);
 46     }
 47 
 48     @Override
 49     public void onClick(View view) {
 50         switch (view.getId()) {
 51         case R.id.btn_nor: // 普通操作
 52             // 延迟3秒回调setCallBackDelay(3000) 执行线程延迟4秒setRunDelay(4000)
 53             UiThread.init(this).setCallBackDelay(3000)
 54                     .showDialog("加载中...", true).setFlag("nor").start(this);
 55             break;
 56         case R.id.btn_get: // get操作
 57             UiThread.init(this).setFlag("get").showDialog("加载中...", false)
 58                     .start(this);
 59             break;
 60         case R.id.btn_image: // 图片请求
 61             UiThread.init(this).setFlag("img").start(this);
 62             break;
 63         case R.id.btn_down: // 下载文件
 64             UiThread.init(this).setFlag("down").start(this);
 65             break;
 66         default:
 67             break;
 68         }
 69     }
 70 
 71     private static String doget() {
 72         String url = "http://ptool.aliapp.com/getip";
 73         HttpGet get = new HttpGet(url);
 74         HttpClient client = new DefaultHttpClient();
 75         try {
 76             HttpResponse response = client.execute(get); // 执行get方法
 77             String resultString = EntityUtils.toString(response.getEntity());
 78             return resultString;
 79         } catch (Exception e) {
 80         }
 81         return null;
 82     }
 83 
 84     private static Bitmap returnBitMap() {
 85         String url = "http://ptool.aliapp.com/QRCodeEncoder?content=im-"
 86                 + (int) (Math.random() * 100);
 87 
 88         URL myFileUrl = null;
 89         Bitmap bitmap = null;
 90         HttpURLConnection conn;
 91         try {
 92             myFileUrl = new URL(url);
 93         } catch (MalformedURLException e) {
 94             e.printStackTrace();
 95         }
 96 
 97         try {
 98             conn = (HttpURLConnection) myFileUrl.openConnection();
 99             conn.setDoInput(true);
100             conn.connect();
101             InputStream is = conn.getInputStream();
102             bitmap = BitmapFactory.decodeStream(is);
103             is.close();
104 
105         } catch (IOException e) {
106             e.printStackTrace();
107         }
108 
109         return bitmap;
110     }
111 
112     public void loadFile(String url, String locPath, String filename,
113             Publisher publisher) {
114         HttpClient client = new DefaultHttpClient();
115         HttpGet get = new HttpGet(url);
116         HttpResponse response;
117         try {
118             response = client.execute(get);
119 
120             HttpEntity entity = response.getEntity();
121             float length = entity.getContentLength();
122 
123             InputStream is = entity.getContent();
124             FileOutputStream fileOutputStream = null;
125             if (is != null) {
126 
127                 String sdcard = Environment.getExternalStorageDirectory()
128                         .getAbsolutePath() + "/" + locPath;
129 
130                 File dir = new File(sdcard);
131                 if (!dir.exists()) { // 不存在则创建
132                     dir.mkdirs();
133                 }
134 
135                 File file = new File(sdcard + "/" + filename);
136                 if (file.exists()) {
137                     file.delete();
138                 } else {
139                     file.createNewFile();
140                 }
141                 fileOutputStream = new FileOutputStream(file);
142                 byte[] buf = new byte[1024];
143                 int ch = -1;
144                 float count = 0;
145                 while ((ch = is.read(buf)) != -1) {
146                     fileOutputStream.write(buf, 0, ch);
147                     count += ch;
148                     float progress = count * 100f / length;
149 
150                     // 发布进度
151                     publisher.publishProgress(progress);
152                 }
153             }
154 
155             // 发布成功
156             publisher.publishProgress(100f);
157 
158             fileOutputStream.flush();
159             if (fileOutputStream != null) {
160                 fileOutputStream.close();
161             }
162         } catch (Exception e) {
163             e.printStackTrace();
164 
165             // 发布下载失败
166             publisher.publishProgress(-1);
167         }
168     }
169 
170     @Override
171     public Object runInThread(String flag, Object obj,
172             UiThread.Publisher publisher) {
173         if (flag.equals("nor")) {
174             for (int i = 0; i < 10; i++) {
175                 try {
176                     Thread.sleep(1000);
177                 } catch (Exception e) {
178                 }
179                 // 可以在线程中发布一个进度,runInUi时 ispublish=true,progress=发布的进度(0-100)
180                 publisher.publishProgress(i * 10);
181             }
182             // 还可以发布一个object,runInUi时 ispublish=true,progress=-1
183             publisher.publishObject(new Bundle());
184 
185             return new Message();
186         } else if (flag.equals("get")) {
187             return doget();
188         } else if (flag.equals("img")) {
189             return returnBitMap();
190         } else if (flag.equals("down")) {
191             // 给个publisher对象让它发布进度
192             loadFile(
193                     "http://dlsw.baidu.com/sw-search-sp/soft/3a/12350/QQ6.1.1406080907.exe",
194                     "Dowbload", "QQsetup.exe", publisher);
195             return "我是object!";
196         }
197         return null;
198     }
199 
200     @Override
201     public void runInUi(String flag, Object obj, boolean ispublish,
202             float progress) {
203         if (flag.equals("nor")) {
204             if (ispublish) {
205                 if (progress == -1) {// 发布的是object
206                     tv.setText("进度:" + progress);
207                 } else {// 发布的是进度
208                     tv.setText("发布的obj:" + obj);
209                 }
210             } else {
211                 tv.setText("返回数据:" + obj);
212             }
213         } else if (flag.equals("get")) {
214             tv.setText("请求结果:" + obj);
215         } else if (flag.equals("img")) {
216             Bitmap bm = (Bitmap) obj;
217             if (bm != null) {
218                 img.setImageBitmap(bm);
219             } else {
220                 tv.setText("加载图片失败!");
221             }
222         } else if (flag.equals("down")) {
223             if (ispublish) {
224                 tv.setText("进度:" + progress);
225             } else {
226                 tv.setText("结果:" + obj);
227             }
228         }
229     }
230 
231 }
原文地址:https://www.cnblogs.com/androidsj/p/4293843.html