UiThread DEMO
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的更多相关文章
- 通过一个demo了解Redux
TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...
- 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo
有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...
- 在线浏览PDF之PDF.JS (附demo)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html#skill 下载地址:http://mozilla.gith ...
- 【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo
Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 ps:最近好久没有写点东西了,项目太紧,今天来一篇 一.本文简介 ...
- vue双向数据绑定原理探究(附demo)
昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与 ...
- Android Studio-—使用OpenCV的配置方法和demo以及开发过程中遇到的问题解决
前提: 1.安装Android Studio(过程略) 2.官网下载OpenCV for Android 网址:http:opencv.org/downloads.html 我下载的是下图的版本 3. ...
- iOS之ProtocolBuffer搭建和示例demo
这次搭建iOS的ProtocolBuffer编译器和把*.proto源文件编译成*.pbobjc.h 和 *.pbobjc.m文件时,碰到不少问题! 搭建pb编译器到时没有什么问题,只是在把*.pro ...
- 钉钉开放平台demo调试异常问题解决:hostname in certificate didn't match
今天研究钉钉的开放平台,结果一个demo整了半天,这帮助系统写的也很难懂.遇到两个问题: 1.首先是执行demo时报unable to find valid certification path to ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
随机推荐
- Android开发--解决AndroidADT开发工具不能代码提示的问题
google android的新的开发工具,打开以后没有代码自动提示功能,下面对ADT工具的一些配置: 1.设置代码的字体 设置JAVA文件代码的字体:我这里设置的14 常规.
- POJ 1191 棋盘分割(DP)
题目链接 题意 : 中文题不详述. 思路 : 黑书上116页讲的很详细.不过你需要在之前预处理一下面积,那样的话之后列式子比较方便一些. 先把均方差那个公式变形, 另X表示x的平均值,两边平方得 平均 ...
- StringUtils.isNumeric使用
在做导入/导出功能时,客户要求导出数字类型的值时,将excel相应单元格属性设为number型,由此需判断字符串值是否为数字,代码如下: public static boolean isNumber( ...
- sql查询数据库中所有表的记录条数,以及占用磁盘空间大小。
SELECT TableName = obj.name, TotalRows = prt.rows, [SpaceUsed(KB)] = SUM(alloc.used_pages)* FROM sys ...
- lintcode:合并排序数组 II
题目: 合并排序数组 II 合并两个排序的整数数组A和B变成一个新的数组. 样例 给出A = [1, 2, 3, empty, empty] B = [4,5] 合并之后A将变成[1,2,3,4,5] ...
- Java学习笔记之:Java封装
一.引言 在面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定 ...
- IDEA使用的点点滴滴
查找一个类可以使用快捷键Ctrl + N 那么怎么看这个类中有哪些属性,哪些方法,就像Eclipse中的outline功能呢? 如查看NIO中的Buffer类,Ctrl + N-->
- MyEclipse 2014GA 新建 Web Project 并配置 SSH
基本软件配置: 1)MyEclipse 2014GA(JDK:内置 1.7.0.u45:SSH:内置 Struts2.1.Spring3.1 和 Hibernate4.1) 2)apache- ...
- AsciiDoc Markup Syntax Summary
AsciiDoc Markup Syntax Summary ============================== A summary of the most commonly used ma ...
- hive 学习笔记——表的入门操作和命令
1.受控表(managed table)包括内部表.分区表.桶表: 1.1.分区表 创建分区表: create table banji(id INT,name STRING) partitioned ...