标签:
在安卓应用中,很多耗时的工作不能放在主线程,即ui线程中进行,因为会导致线程堵塞,使得系统判断程序运行异常,所以,需要多线程来进行异步操作,Android中提供了两种多线程的实现方式,此处注意,只要涉及ui更新的都必须要在主线程中进行
1.Handler
handler有两个重要的构造方式,一个是空参数的,一个是带有Looper的,用空参数的方式生成的handler是和当前的线程关联的,一般是主线程,另一种是也可以为它提供一个Looper,这样它就会绑定到Looper所在的线程上。Handler为不同线程之间的通信提供了方便。要和另外一个线程通信,只要得到它的Handler就行了。一个handler只能和一个线程关联
Android中提供了handlerthread类
这个类本身就是一个支持消息循环的线程类。注意要启动一个线程还是需要手动调用start()的。
对于一个HandlerThread,可以用getLooper()来得到它的Looper,但是要注意必须在这之前用start()启动了线程,不然是Looper是空的
Handler的最大好处在于,它不只可以发送消息,还可以用post()来发送一个Runnable。这样一来,就可以在指定进程里面执行Runnable的run()方法中的代码了,也就是跨线程方法调用
例如:
public class MainActivity extends Activity { private Handler handler; private Handler handlerthree; private Runnabletwo runnabletwo; public void onCreate(....) { HandlerThread thread = new HandlerThread("threadthree"); thread.start(); //一定要先start(),然后才能getlooper handlerthree = new Handlerthree(thread.getlooper()); handlerthree.post(runnabletwo); } Handler handler = new Handler(){ 复写handlemessage方法; .......... } RunnableTwo runnabletwo =new Runnable(){ 复写run方法,最后可以用handler.sendmessage();方法与主线程通信进行Ui更新 } class Handlerthree extends Handler{ public Handlerthree(Looper looper) { super(looper); } } }
2.AsyncTask
Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:
有必要的话你还得重写以下这三个方法,但不是必须的:
使用AsyncTask类,以下是几条必须遵守的准则:
AsyncTask的三个泛型参数说明(三个参数可以是任何类型)
第一个参数:传入doInBackground()方法的参数类型 第二个参数:传入onProgressUpdate()方法的参数类型 第三个参数:传入onPostExecute()方法的参数类型,也是doInBackground()方法返回的类型
其中在主线程中new 一个asynctask的实现类,然后执行.execute(params),这里params在实际使用时候需要赋值,该值被传到doinbackground()方法里面
例如一个实现了继承了AsyncTask的Task类
public class Task extends AsyncTask<Integer, Integer, String>{ private TextView view ; private ProgressBar bar; public Task(TextView view,ProgressBar bar){ super(); this.view = view; this.bar = bar; } /** * 这里的Integer参数对应AsyncTask中的第一个参数 * 这里的String返回值对应AsyncTask的第三个参数 * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改 * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作 */ @Override protected String doInBackground(Integer... params) { NetOperator netOperator = new NetOperator(); int i = 0; for (i = 10; i <= 100; i+=10) { netOperator.operator(); publishProgress(i); } return i + params[0].intValue() + ""; } /** * 这里的Intege参数对应AsyncTask中的第二个参数 * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行 * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作 */ @Override protected void onProgressUpdate(Integer... values) { int vlaue = values[0]; bar.setProgress(vlaue); } /** * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值) * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置 */ @Override protected void onPostExecute(String result) { view.setText("异步操作执行结束" + result); } //该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置 @Override protected void onPreExecute() { view.setText("开始执行异步线程"); } }
多线程在Android应用开发中应用广泛,很重要!
Android 线程问题 handler & synctask
标签:
原文地址:http://www.cnblogs.com/lingxianxia/p/4301180.html