import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message; public class UiThread {
private static Context mainContext;
private static Handler mainHandler;
private static ExecutorService pool;
// 最大执行线程数量
private static final int MAXTHREADCOUNT = 5; private Object obj; // 运行时需要的obj
private String flag = ""; // 防止null
private long runDelayMillis; // 运行前延迟
private long callbackDelayMills; // 回调前延时
private Dialog dialog;
private UIThreadEvent event;
private UIpublisher publisher;
private Object back;
private Context context; public interface UIThreadEvent {
public Object runInThread(String flag, Object obj, Publisher publisher); public void runInUi(String flag, Object obj, boolean ispublish,
float progress);
} public interface Publisher {
public void publishProgress(float progress); public void publishObject(Object object);
} public class PublishData {
Object obj;
float progress;
UiThread uithread;
} public static UiThread init(Context content) {
return new UiThread((Activity) content);
} public class UIpublisher implements Publisher {
public UiThread uithread; public UIpublisher(UiThread uithread) {
this.uithread = uithread;
} @Override
public void publishProgress(float progress) {
PublishData data = new PublishData();
data.uithread = uithread;
data.progress = progress;
data.obj = null; Message msg = Message.obtain();
msg.obj = data;
mainHandler.sendMessage(msg);
} @Override
public void publishObject(Object object) {
PublishData data = new PublishData();
data.uithread = uithread;
data.progress = -1;
data.obj = object; Message msg = Message.obtain();
msg.obj = data;
mainHandler.sendMessage(msg);
} } public UiThread(Activity activity) {
this.context = activity;
if (mainHandler == null || mainContext != context) {
mainContext = context; if (Looper.myLooper() != Looper.getMainLooper()) {
throw new InternalError("uiThread cannot init from thread!");
} mainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg == null)
return; Object obj = msg.obj;
if (obj instanceof UiThread) {
UiThread data = (UiThread) obj;
// 如果是activity,finish后就不回调mainthread
if (context instanceof Activity) {
if (((Activity) data.context).isFinishing()) {
return;
}
} if (data.dialog != null) {
// 关闭加载窗
data.dialog.dismiss();
}
data.event.runInUi(data.flag, data.back, false, -1); // 清理
data.dialog = null;
data.event = null;
data.publisher = null;
data = null;
} else if (obj instanceof PublishData) {
PublishData data = (PublishData) obj; if (data.uithread.dialog instanceof ProgressDialog) {
// 如果设置显示了ProgressDialog,自动更新dialog的进度
if (data.uithread.dialog.isShowing()
&& data.progress > 0 && data.progress < 100) {
((ProgressDialog) data.uithread.dialog)
.setMessage(data.progress + "%");
}
} data.uithread.event.runInUi(data.uithread.flag,
data.obj, true, data.progress); // 清理
data.uithread = null;
data.obj = null;
data = null;
}
msg.obj = null;
}
};
}
if (pool == null) {
pool = Executors.newFixedThreadPool(MAXTHREADCOUNT); // 固定线程池
}
} public UiThread setFlag(String flag) {
this.flag = flag;
return this;
} public UiThread setObject(Object obj) {
this.obj = obj;
return this;
} public UiThread showDialog(Dialog dialog) {
if (this.dialog != null) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
} this.dialog = dialog;
return this;
} public UiThread showDialog(String tip, boolean canCancel) {
if (dialog != null) {
if (dialog.isShowing()) {
dialog.dismiss();
}
} if (tip == null) {
dialog = ProgressDialog.show(context, null, "加载中", true, canCancel,
null);
} else {
dialog = ProgressDialog.show(context, null, tip, true, canCancel,
null);
}
return this;
} public UiThread setRunDelay(long delayMillis) {
this.runDelayMillis = delayMillis;
return this;
} public UiThread setCallBackDelay(long delayMillis) {
this.callbackDelayMills = delayMillis;
return this;
} public void start(UIThreadEvent event) {
this.event = event;
publisher = new UIpublisher(this); if (dialog != null) {
dialog.show();
} pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(runDelayMillis);
} catch (Exception e) {
e.printStackTrace();
}
UiThread.this.back = UiThread.this.event.runInThread(flag, obj,
publisher);
Message msg = Message.obtain();
msg.obj = UiThread.this;
mainHandler.sendMessageDelayed(msg, callbackDelayMills);
}
});
}
}
 import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils; import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView; import com.yunxun.tool.UiThread;
import com.yunxun.tool.UiThread.Publisher;
import com.yunxun.tool.UiThread.UIThreadEvent; public class MainActivity extends Activity implements OnClickListener,
UIThreadEvent {
TextView tv;
ImageView img; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
img = (ImageView) findViewById(R.id.img);
findViewById(R.id.btn_get).setOnClickListener(this);
findViewById(R.id.btn_image).setOnClickListener(this);
findViewById(R.id.btn_nor).setOnClickListener(this);
findViewById(R.id.btn_down).setOnClickListener(this);
} @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_nor: // 普通操作
// 延迟3秒回调setCallBackDelay(3000) 执行线程延迟4秒setRunDelay(4000)
UiThread.init(this).setCallBackDelay(3000)
.showDialog("加载中...", true).setFlag("nor").start(this);
break;
case R.id.btn_get: // get操作
UiThread.init(this).setFlag("get").showDialog("加载中...", false)
.start(this);
break;
case R.id.btn_image: // 图片请求
UiThread.init(this).setFlag("img").start(this);
break;
case R.id.btn_down: // 下载文件
UiThread.init(this).setFlag("down").start(this);
break;
default:
break;
}
} private static String doget() {
String url = "http://ptool.aliapp.com/getip";
HttpGet get = new HttpGet(url);
HttpClient client = new DefaultHttpClient();
try {
HttpResponse response = client.execute(get); // 执行get方法
String resultString = EntityUtils.toString(response.getEntity());
return resultString;
} catch (Exception e) {
}
return null;
} private static Bitmap returnBitMap() {
String url = "http://ptool.aliapp.com/QRCodeEncoder?content=im-"
+ (int) (Math.random() * 100); URL myFileUrl = null;
Bitmap bitmap = null;
HttpURLConnection conn;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
} try {
conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close(); } catch (IOException e) {
e.printStackTrace();
} return bitmap;
} public void loadFile(String url, String locPath, String filename,
Publisher publisher) {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get); HttpEntity entity = response.getEntity();
float length = entity.getContentLength(); InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) { String sdcard = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/" + locPath; File dir = new File(sdcard);
if (!dir.exists()) { // 不存在则创建
dir.mkdirs();
} File file = new File(sdcard + "/" + filename);
if (file.exists()) {
file.delete();
} else {
file.createNewFile();
}
fileOutputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int ch = -1;
float count = 0;
while ((ch = is.read(buf)) != -1) {
fileOutputStream.write(buf, 0, ch);
count += ch;
float progress = count * 100f / length; // 发布进度
publisher.publishProgress(progress);
}
} // 发布成功
publisher.publishProgress(100f); fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (Exception e) {
e.printStackTrace(); // 发布下载失败
publisher.publishProgress(-1);
}
} @Override
public Object runInThread(String flag, Object obj,
UiThread.Publisher publisher) {
if (flag.equals("nor")) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
// 可以在线程中发布一个进度,runInUi时 ispublish=true,progress=发布的进度(0-100)
publisher.publishProgress(i * 10);
}
// 还可以发布一个object,runInUi时 ispublish=true,progress=-1
publisher.publishObject(new Bundle()); return new Message();
} else if (flag.equals("get")) {
return doget();
} else if (flag.equals("img")) {
return returnBitMap();
} else if (flag.equals("down")) {
// 给个publisher对象让它发布进度
loadFile(
"http://dlsw.baidu.com/sw-search-sp/soft/3a/12350/QQ6.1.1406080907.exe",
"Dowbload", "QQsetup.exe", publisher);
return "我是object!";
}
return null;
} @Override
public void runInUi(String flag, Object obj, boolean ispublish,
float progress) {
if (flag.equals("nor")) {
if (ispublish) {
if (progress == -1) {// 发布的是object
tv.setText("进度:" + progress);
} else {// 发布的是进度
tv.setText("发布的obj:" + obj);
}
} else {
tv.setText("返回数据:" + obj);
}
} else if (flag.equals("get")) {
tv.setText("请求结果:" + obj);
} else if (flag.equals("img")) {
Bitmap bm = (Bitmap) obj;
if (bm != null) {
img.setImageBitmap(bm);
} else {
tv.setText("加载图片失败!");
}
} else if (flag.equals("down")) {
if (ispublish) {
tv.setText("进度:" + progress);
} else {
tv.setText("结果:" + obj);
}
}
} }

UiThread DEMO的更多相关文章

  1. 通过一个demo了解Redux

    TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...

  2. 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo

    有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...

  3. 在线浏览PDF之PDF.JS (附demo)

    平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html#skill 下载地址:http://mozilla.gith ...

  4. 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo

    Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...

  5. vue双向数据绑定原理探究(附demo)

    昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与 ...

  6. Android Studio-—使用OpenCV的配置方法和demo以及开发过程中遇到的问题解决

    前提: 1.安装Android Studio(过程略) 2.官网下载OpenCV for Android 网址:http:opencv.org/downloads.html 我下载的是下图的版本 3. ...

  7. iOS之ProtocolBuffer搭建和示例demo

    这次搭建iOS的ProtocolBuffer编译器和把*.proto源文件编译成*.pbobjc.h 和 *.pbobjc.m文件时,碰到不少问题! 搭建pb编译器到时没有什么问题,只是在把*.pro ...

  8. 钉钉开放平台demo调试异常问题解决:hostname in certificate didn't match

    今天研究钉钉的开放平台,结果一个demo整了半天,这帮助系统写的也很难懂.遇到两个问题: 1.首先是执行demo时报unable to find valid certification path to ...

  9. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

随机推荐

  1. SDUT2482二叉排序树

    http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2482&cid=1184 题目描述 二叉排序树的定义是:或者是一棵空树,或者是具有下列性质 ...

  2. Bessie的体重问题

    P1028 Bessie的体重问题 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 USACO OCT09 8TH  描述 Bessie像她的诸多姊妹一样,因 ...

  3. lintcode:四个数之和

    题目 四数之和 给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d). 样例 例如,对于给定的整数数组S=. 满足要求的四元组集合为: (-1, 0 ...

  4. 为什么需要用到序列化?为什么HttpSession中对象要序列化

    简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比你自己好的保存对象状态的 ...

  5. php相关学习资源

    相关书籍资源: 1:PHP和MySQL Web开发 经典书籍 视频教程: PHP开发工程师闯关记--初识PHP php调试技巧: PHP 程序员的调试技术 使用 print 语句.错误报告和 PHPE ...

  6. Intellij IDEA调试功能

    public class Demo { public static void f1() { System.out.println("one"); System.out.printl ...

  7. pancake sort的几个问题

    1. 每次找剩下序列中的最大值,可以进行pancake sort,时间复杂度是O(n^2): 2. 求最少交换次数进行pancake sort的问题是个NP问题,搜索的时候,upper bound是2 ...

  8. 简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现。

    简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现. 题目: Suppose a sorted array is rotated at som ...

  9. 修改tabbarcontroller选中图片及选中颜色

    1.修改选中图片: UITabBarItem* item = [self.tabBarController.tabBar.items objectAtIndex:1];   //从0开始 item.s ...

  10. WPF中的Drawing

    以前在用WinForm的时候,可以通过GDI+接口在窗体上动态绘制自定义的图形.在WPF中有没有对应的API呢,最近项目中用到了这个,在这里总结一下. WPF中的Drawing主要提供了几类API: ...