Android之开发中用到的几个多线程解析
2015-10-10 19:06
537 查看
在开发工程中线程可以帮助我们提高运行速度,Android开发中我知道的线程有四个一个是老生长谈的Thread,第二个是asyncTask,第三个:TimetTask,第四个是Looper,四个多线程各有个的有点,Thread的运行速度是最快的,AsyncTask的规范性是最棒的,其它两个也有自己的优点,下面先贴上三个列子
1.Thread与Handler组合,比较常见
Handler主要是帮助我们来时时更新UI线程
这里在后天加载100张图片,然后没加载完成一个用handler 返回给UI线程一张图片并显示
最后加载完成返回一个List给UI线程 ,Handler就是一个后台线程与UI线程中间的桥梁
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 =0;
/**图片列表**/
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 =0;i<100;i++){
Bitmap bitmap =ReadBitmap(mContext,R.drawable.icon);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, 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[0];
byte[] image = bundle.getByteArray("image");
Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, 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);
}
}
3TimerTask
可以根据我们的设置来间隔性的运行,可以很好的实现监听功能一般也跟handler一起
1.Thread与Handler组合,比较常见
Handler主要是帮助我们来时时更新UI线程
这里在后天加载100张图片,然后没加载完成一个用handler 返回给UI线程一张图片并显示
最后加载完成返回一个List给UI线程 ,Handler就是一个后台线程与UI线程中间的桥梁
package com.android.wei.thread; 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 =0; /**标志读取进度结束**/ public final static int LOAD_COMPLETE = 1; /**开始加载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 =0;i<100;i++){ Bitmap bitmap=ReadBitmap(mContext,R.drawable.icon); Message msg = new Message(); msg.what = LOAD_PROGRESS; msg.arg1 = i+1; 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 =0;
/**图片列表**/
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 =0;i<100;i++){
Bitmap bitmap =ReadBitmap(mContext,R.drawable.icon);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, 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[0];
byte[] image = bundle.getByteArray("image");
Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, 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);
}
}
3TimerTask
可以根据我们的设置来间隔性的运行,可以很好的实现监听功能一般也跟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 =0; /**关闭TImer进度**/ public final static int CLOSE_PROGRESS =1; /**开始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 =0; 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, 1000,1000); } } public void CloseTimer(){ if(mTimer !=null){ mTimer.cancel(); mTimer = null; } if(mTimerTask!= null){ mTimerTask = null; } mTimerID =0; handler.sendEmptyMessage(CLOSE_PROGRESS); } }
相关文章推荐
- Android 5.1 Contacts源码分析(五):PeopleActivity
- Android 沉浸模式开发
- Android 6.0 新增API 简介(2)
- android studio 使用SVN 锁定文件,防止别人修改(基于Android studio 1.4 )
- android 設置dialog点击空白处,界面不杀死
- Android Custom View NullPointerException
- android 5.0新特性 RecyclerView使用初级
- Android——在一个Activity中如何启动另外一个Activity
- 找Android程序登录按钮事件
- Android Tips
- Android Environment类的接口详解
- Android 禁止屏幕旋转 和 旋转屏幕时保持Activity
- Android 源码获取——在Windows环境下通过Git得到Android源代码
- Android中的GraphicBuffer同步机制-Fence
- Android之菜单总结
- Android基础
- Android Studio in OSX 提高工作效率的快捷键
- android GestureListener手势,多指缩放
- 从源码角度分析Android系统的异常捕获机制是如何运行的
- Android 如何让EditText不自动获取焦点