Android 开发中三种多线程
在开发工程中线程可以帮助我们提高运行速度,Android开发中我知道的线程有四个一个是老生长谈的Thread,第二个是asyncTask,第三个:TimetTask,第四个是Looper,四个多线程各有个的有点,Thread的运行速度是最快的,AsyncTask的规范性是最棒的,其它两个也有自己的优点。
1.Thread与Handler组合,比较常见
Handler主要是帮助我们来时时更新UI线程
这里在后天加载100张图片,然后没加载完成一个用handler 返回给UI线程一张图片并显示
最后加载完成返回一个List给UI线程 ,Handler就是一个后台线程与UI线程中间的桥梁
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView; public class Activity01 extends Activity {
/** Called when the activity is first created. */ /**读取进度**/
public final static int LOAD_PROGRESS =; /**标志读取进度结束**/
public final static int LOAD_COMPLETE = ;
/**开始加载100张图片按钮**/
Button mButton = null; /**显示内容**/
TextView mTextView = null; /**加载图片前的时间**/
Long mLoadStart = 0L;
/**加载图片完成的时间**/
Long mLoadEndt = 0L; Context mContext = null;
/**图片列表**/
private List<Bitmap> list;
/**图片容器**/
private ImageView mImageView;
//接受传过来得消息
Handler handler = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case LOAD_PROGRESS:
Bitmap bitmap = (Bitmap)msg.obj;
mTextView.setText("当前读取到第"+msg.arg1+"张图片");
mImageView.setImageBitmap(bitmap);
break;
case LOAD_COMPLETE:
list = (List<Bitmap>) msg.obj;
mTextView.setText("读取结束一共加载"+list.size()+"图片");
break;
}
super.handleMessage(msg);
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.main);
mButton =(Button) findViewById(R.id.button1);
mTextView=(TextView) findViewById(R.id.textView1);
mImageView =(ImageView) this.findViewById(R.id.imageview);
mTextView.setText("点击按钮加载图片");
mButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
//调用方法
LoadImage();
}
}); }
public void LoadImage(){
new Thread(){
public void run(){
mLoadStart = System.currentTimeMillis();
List<Bitmap> list = new ArrayList<Bitmap>();
for(int i =;i<;i++){
Bitmap bitmap=ReadBitmap(mContext,R.drawable.icon);
Message msg = new Message();
msg.what = LOAD_PROGRESS;
msg.arg1 = i+;
list.add(bitmap);
msg.obj = bitmap;
handler.sendMessage(msg);
}
mLoadEndt = System.currentTimeMillis();
Message msg = new Message();
msg.what = LOAD_COMPLETE;
msg.obj=list;
msg.arg1 = (int) (mLoadEndt - mLoadStart);
handler.sendMessage(msg); }
}.start();
}
public Bitmap ReadBitmap(Context context,int resId){
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
}
2.AsyncTask异步多线程
AsyncTask的规范型很强,能够时时反映更新的情况
它一般有这么几个方法
* onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
* doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
* onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
* onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.
* onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI 线程中创建
2) execute方法必须在UI 线程中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法,需要在UI线程中实例化这个task来调用。
4) 该task只能被执行一次,否则多次调用时将会出现异常
package com.android.wei.thread; import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask; import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView; public class Activity02 extends Activity{ /**开始StartAsync按钮**/
Button mButton = null; Context mContext = null; //内容显示出来
TextView mTextView = null; //Timer 对象
Timer mTimer = null; /** timerTask 对象**/
TimerTask mTimerTask = null; /**记录TimerId**/
int mTimerId =;
/**图片列表**/
private List<Bitmap> list;
/**图片容器**/
private ImageView mImageView;
public void onCreate(Bundle s){
super.onCreate(s);
setContentView(R.layout.main);
mContext = this;
mButton =(Button) this.findViewById(R.id.button1);
mImageView =(ImageView)this.findViewById(R.id.imageview);
mTextView =(TextView) this.findViewById(R.id.textView1);
mButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
StartAsync();
}
}); }
public void StartAsync(){
new AsyncTask<Object,Object,Object>(){
protected void onPreExecute(){
//首先执行这个方法,它在UI线程中,可以执行一些异步操作
mTextView.setText("开始加载进度");
super.onPreExecute();
}
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
//异步后台执行,执行完毕可以返回出去一个结果 Object 对象
//得到开始加载得时间
list = new ArrayList<Bitmap>();
for(int i =;i<;i++){
Bitmap bitmap =ReadBitmap(mContext,R.drawable.icon);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, , os);
byte[] image = os.toByteArray();
Bundle bundle = new Bundle();
bundle.putInt("index", i);
bundle.putByteArray("image", image);
publishProgress(bundle);
list.add(bitmap); } return list;
}
protected void onPostExecute(Object result){
//doInBackground 执行之后在这里可以接受到返回结果的对象
List<Bitmap> list = (List<Bitmap>) result;
mTextView.setText("一共加载了"+list.size()+"张图片");
super.onPostExecute(result);
}
protected void onProgressUpdate(Object... values){
//时时拿到当前的进度更新UI
Bundle bundle = (Bundle)values[];
byte[] image = bundle.getByteArray("image");
Bitmap bitmap = BitmapFactory.decodeByteArray(image, , image.length);
int index = bundle.getInt("index");
mTextView.setText("当前加载进度"+index);
mImageView.setImageBitmap(bitmap);
super.onProgressUpdate(values);
} }.execute();
}
public Bitmap ReadBitmap(Context context,int resId){
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
} }
3.TimerTask
可以根据我们的设置来间隔性的运行,可以很好的实现监听功能一般也跟handler一起
package com.android.wei.thread; import java.util.Timer;
import java.util.TimerTask; import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class TimerTaskActivity extends Activity{
/**执行Timer进度**/
public final static int LOAD_PROGRESS =; /**关闭TImer进度**/
public final static int CLOSE_PROGRESS =; /**开始TIMERTASK按钮**/
Button mButton0 = null; /**关闭TIMERTASK按钮**/
Button mButton1 =null; /**显示内容**/
TextView mTextView = null; Context mContext = null; /**timer对象**/
Timer mTimer = null; /**TimerTask对象**/
TimerTask mTimerTask = null; /**记录TimerID**/
int mTimerID =; Handler handler = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case LOAD_PROGRESS:
mTextView.setText("当前得TimerID为:"+msg.arg1);
break;
case CLOSE_PROGRESS:
mTextView.setText("当前Timer已经关闭请重新启动");
break;
}
super.handleMessage(msg);
}
};
protected void onCreate(Bundle s){
setContentView(R.layout.timer);
mContext = this;
mButton0 = (Button) this.findViewById(R.id.button1);
mButton1 = (Button) this.findViewById(R.id.button2);
mTextView = (TextView) this.findViewById(R.id.textView1);
mTextView.setText("点击按钮开始更新时间");
mButton0.setOnClickListener(new OnClickListener(){
public void onClick(View v){
StartTimer();
}
});
mButton1.setOnClickListener(new OnClickListener(){
public void onClick(View v){
CloseTimer();
}
});
super.onCreate(s);
}
public void StartTimer(){
if(mTimer == null){
mTimerTask = new TimerTask(){ @Override
public void run() {
mTimerID ++;
Message msg = new Message();
msg.what = LOAD_PROGRESS;
msg.arg1 =(int) (mTimerID);
handler.sendMessage(msg); } };
mTimer = new Timer();
//第一个参数为执行的mTimerTask
//第二个参数为延迟得事件,这里写1000得意思是 mTimerTask将延迟1秒执行
//第三个参数为多久执行一次,这里写1000 表示没1秒执行一次mTimerTask的Run方法
mTimer.schedule(mTimerTask, ,);
}
}
public void CloseTimer(){
if(mTimer !=null){
mTimer.cancel();
mTimer = null;
}
if(mTimerTask!= null){
mTimerTask = null;
}
mTimerID =;
handler.sendEmptyMessage(CLOSE_PROGRESS);
}
}
Android 开发中三种多线程的更多相关文章
- iOS开发UI篇—iOS开发中三种简单的动画设置
iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...
- Android开发中几种有用的的日历控件实现
我们大家都知道,在Android平台3.0中才新增了日历视图控件,可以显示网格状的日历内容,那么对于3.0以下的版本要使用日历控件只能借助第三方,目前用的最多的是CalendarView. 先简单介绍 ...
- ios中三种多线程的技术对比
1.NSThread 使用较少 在NSThread调用的方法中,同样要使用autoreleasepool进行内存管理,否则容易出现内存泄露. 使用流程:创建线程-->启动线程 2.NSOpera ...
- android开发中的5种存储数据方式
数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences ...
- 在Android开发中,定时器一般有以下3种实现方法
在Android开发中,定时器一般有以下3种实现方法: 原文地址http://www.360doc.com/content/12/0619/13/87000_219180978.shtml 一.采用H ...
- 在Android开发中,定时执行任务的3种实现方法
在Android开发中,定时执行任务的3种实现方法: 一.采用Handler与线程的sleep(long)方法(不建议使用,Java的实现方式)二.采用Handler的postDelayed(Runn ...
- 怎样在Android开发中FPS游戏实现的两种方式比较
怎样在Android开发中FPS游戏实现的两种方式比较 如何用Android平台开发FPS游戏,其实现过程有哪些方法,这些方法又有哪些不同的地方呢?首先让我们先了解下什么是FPS 英文名:FPS (F ...
- wemall app商城源码中android按钮的三种响应事件
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码中android按 ...
- Android中三种计时器Timer、CountDownTimer、handler.postDelayed的使用
在android开发中,我们常常需要用到计时器,倒计时多少秒后再执行相应的功能,下面我就分别来讲讲这三种常用的计时的方法. 一.CountDownTimer 该类是个抽象类,如果要使用这个类中的方法, ...
随机推荐
- java程序连接hive数据库遇到的问题
今天,打算学习一下用hadoop做后台,搭建一个网站,首先第一步便是在本机的eclipse中连接到虚拟机上的hive中,原本以为很简单,但是过程很是艰难.特意做总结 首先hive的版本问题就是一个很大 ...
- DIV居中的几种方法
1. body{ text-align:center; } 缺点:body内所有内容一并居中 2. .center{ position: fixed; left: 50%; } 缺点:需要设置posi ...
- redis允许内网访问
如题有A.B两台服务器. A服务器上装有reis,内网IP:192.168.0.1 B服务器需要访问A服务器上的redis 一.修改A服务器上redis.conf文件 bind 192.168.0.1 ...
- 下拉菜单;手风琴;九宫格的Jquery的使用实例
下拉菜单;手风琴;九宫格的Jquery的使用实例 1.下拉菜单 效果如图: 代码如下: <!DOCTYPE html> <html lang="en"> & ...
- Android 开发工具类 11_ToolFor9Ge
1.缩放/ 裁剪图片: 2.判断有无网络链接: 3.从路径获取文件名: 4.通过路径生成 Base64 文件: 5.通过文件路径获取到 bitmap: 6.把 bitmap 转换成 base64: 7 ...
- 分区助手官网使用教程(专业版、绿色版和WinPE版)(图文详解)
不多说,直接上干货! 详情见 http://www.disktool.cn/jiaocheng/index.html http://www.disktool.cn/jiaocheng/index2.h ...
- 笔记一:python安装和执行
一:学习内容 python安装 python简介 python执行 二:python安装 1. 下载python,网地址:https://www.python.org/,进入地址后,点击下载downl ...
- java Html 转 PDF
Html 转 PDF 使用 flying-saucer 插件来完成 导入flying-saucer依赖 <dependency> <groupId>org.xhtmlrende ...
- 笔记:css3伪选择器改变滚动条样式
现在我打开支持前缀-webkit-的浏览器,也就是说只要支持前缀为-webkit-的浏览器才有效果 <!doctype html> <html lang="en" ...
- Behave step matcher
behave 提供3中step匹配模式 'parse' 'cfparse' 基于parse的扩展, 支持cardinality field syntax? 're' 支持在step中定义正则表达式 ...