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&#39;t match

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

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

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

随机推荐

  1. Frequently Asked Questions - P-thresholds

    Source: http://mindhive.mit.edu/book/export/html 1. What is the multiple-comparison problem? What is ...

  2. 44个 Javascript 变态题解析 (上\下)

    第1题 ["1", "2", "3"].map(parseInt) 知识点: Array/map Number/parseInt JavaS ...

  3. iOS开发之APP推送设置WIFI

    在iOS开发过程中,有时需要连接网络.当访问请求,检测到网络不可用时,需要提示用户手动进行设置网络并告知用户操作路径设置可用的网络. 只需一行代码即可实现: - (void)viewDidLoad { ...

  4. Codeforces Round #326 (Div. 2)-Duff and Meat

    题意: Duff每天要吃ai千克肉,这天肉的价格为pi(这天可以买好多好多肉),现在给你一个数值n为Duff吃肉的天数,求出用最少的钱满足Duff的条件. 思路: 只要判断相邻两天中,今天的总花费 = ...

  5. 在 Fedora 里安装自带的 MATE和 cinnamon

    参见  http://wiki.mate-desktop.org/download#fedora安装方法: yum groupinstall mate-desktop yum groupinstall ...

  6. javascript 模仿 html5 placeholder

    <form action="?action=deliver" method="post" class="deliver-form"&g ...

  7. YIi配置debug工具、yii配置gii工具

    $config['bootstrap'][] = 'debug';$config['modules']['debug'] = [ 'class'=>'yii\debug\Module', 'al ...

  8. 让shell 变得容易理解

    1.重建你的语义模型(简单语义模型)2.变量,参数和方法命名3.测试用例4.足够的组块

  9. html缓存控制

  10. LeetCode--290--单词模式

    问题描述: 给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式. 这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之 ...