AsyncTask,Handler,Looper,MessageQueue

         一堆东西,AsyncTask、Handler、Looper、MessageQueue。容我一个一个看过来,该翻译的翻译,该写demo的写demo。当然可能不会写的太过深入,因为每个都展开来的话都可以写一篇博客了,这里以了解为主。

         一、Handler

         Handler在程序中用的还是比较多的,通常会使用Handler在UI线程和后台线程之间传递消息(Message)。UI线程(通常就是主线程)可以根据得到的消息来更新UI组件。下面是本人对API中Handler文档的翻译,英语水平有限,高手勿喷哈

         <译>你可以使用一个Handler对象通过发送或处理Message及Runnable对象来实现和某一线程的MessageQueue交互的功能。每个Handler对象只和某一个线程以及该线程的消息队列交互。当你创建一个线程时,它会被绑定到那个创建它的线程或消息队列上,从那是起,它就可以向那个消息队列发送Message或runnable对象,并在这些对象出队列时处理它们。

          Handler主要有两个用处:(1)安排一些计划在未来某个时间点处理的Message或Runnable对象。(2)为其他线程安排一个动作(Message或Runnable)。

          安排消息是通过post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable,long)、sendEmptyMessage(int)、sendMessage(Message)、sendMessageAtTime(Message,long)、sendMessageDelayed(Message,long)这些方法实现的。其中post系列方法使你能够添加消息队列中添加Runnable,这些Runnable对象将在被接收到时执行。send系列方法使你能够像消息队列中添加包含bundle数据的Message对象,这些Message对象会在Handler的handlerMessage(Message)方法中被处理。</译>

           OK,Handler这一块关于什么想队列中添加Message或Runnable都是很简单的,这里就不扯了。上边的红字"为其他线程安排一个动作(Message或Runnable)“,一起到没注意到,下面就写个demo。

           新建一个Android工程,在主界面MainActivity中包含一个按钮,单击按钮将启动一个新的线程,在线程中有一个Handler的消息处理,可以在单击事件时从主线程向自定义线程MyThread的消息队列中添加一个动作,详细代码如下:

<span style="font-size:18px;">package com.wly.tasktest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity implements OnClickListener{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		findViewById(R.id.Enqueue_Action_In_Other_Thread).setOnClickListener(this);
		System.out.println(Thread.currentThread().getName()); //syso:main
		
	}
	
	@Override
	public void onClick(View v) {
		switch(v.getId()) {
		case R.id.Enqueue_Action_In_Other_Thread:
			MyThread myThread = new MyThread();
			myThread.start();
			
			//为另外的线程添加动作
			Message msg = new Message();
			msg.obj = "来自主线程的一个Message";
			myThread.getHandler().sendMessage(msg);
			break;
		}
	}
	
	class MyThread extends Thread {

		Handler handler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				System.out.println("received msg with obj:" + msg.obj.toString()); //syso:Thread-1764
			}
		};
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			int i = 0;
			System.out.println(Thread.currentThread().getName());
			while(i < 10) {
				Message msg = new Message();
				msg.obj = i + "";
				handler.sendMessageDelayed(msg, 1000);
				i ++;
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
		public Handler getHandler() {
			return handler;
		}
	}
}
</span>

          单击按钮后的运行结果如下:

          二、Looper

          Looper从字面意义上是"循环者","循环器",它是一个MessageQueue的管理者,除了主线程有一个默认的Looper对象,而创建Looper对象时会自动创建一个Message Queue对象。 即主线程会默认有一个Looper和Messge Queue对象,而其他非主线程则是没有的。要为非主线程关联Looper对象的话,需要调用prepare方法实现,然后再调用loop方法开始消息的循环处理。下面是Android API中Looper的翻译。

         <译>用来为一个线程执行一个消息循环的类。默认情况线程是没有与之交互的消息队列的;想要创建一个这样的消息队列,可以在希望运行消息循环的线程上调用prepare方法,然后调用loop方法来开始消息循环的处理。</译>

         三、MessageQueue

         从MessageQueue的方法就可以看出MessageQueue其实就是一个队列的数据结构,不过里面放的是Message类型的数据对象。

         <译>一个低层次的用来存储Looper所分发的Message的类。Message不是直接被添加到MessageQueue中去的,而是通过和Looper交互MessageQueue.IdleHandler来实现的。你可以通过调用Looper.myQueue()来得到当前线程的MessageQueue。</译>

         四、AsyncTask

         <译>AsyncTask对UI线程来说是易用、方便的。这个类可以在不手动操作线程或Handler的情况下,将后台操作的结果反馈给UI线程。

         AsyncTask的设计目的是作为一个Thread和Handler的帮助类,而不是通常意义上的线程框架。AsyncTask对于短时操作(最多几秒)来说是十分合适的。假如你需要一个耗时很长的线程,那么我们极力推荐你使用java.util.concurrent报下的其他API,如Executor,ThreadPoolExecutror以及FutureTask。</译>

        下面是一个AsyncTask的简单Demo,注意AsyncTas是一个抽象类,不能直接实例化,但是可以使用匿名对象,为什么呢?这个我会在本文的最后加以解释。最后代码变成这样了

<span style="font-size:18px;">package com.wly.tasktest;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{

	TextView tv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		findViewById(R.id.Enqueue_Action_In_Other_Thread).setOnClickListener(this);
		System.out.println(Thread.currentThread().getName()); //syso:main
		
		findViewById(R.id.testAsyncTask).setOnClickListener(this);
		
		tv = (TextView)findViewById(R.id.textView1);
	}
	
	@Override
	public void onClick(View v) {
		switch(v.getId()) {
		case R.id.Enqueue_Action_In_Other_Thread:
			MyThread myThread = new MyThread();
			myThread.start();
			
			//为另外的线程添加动作
			Message msg = new Message();
			msg.obj = "来自主线程的一个Message";
			myThread.getHandler().sendMessage(msg);
			break;
		case R.id.testAsyncTask:
			
			new AsyncTask<Void, String, String>() {

				@Override
				protected void onPostExecute(String result) {
					// TODO Auto-generated method stub
					super.onPostExecute(result);
				}

				//做一些准备动作
				@Override
				protected void onPreExecute() {
					// TODO Auto-generated method stub
					super.onPreExecute();
				}

				//更新进度
				@Override
				protected void onProgressUpdate(String... values) {
					// TODO Auto-generated method stub
					super.onProgressUpdate(values);
					tv.setText(values[0].toString());

				}

				@Override
				protected String doInBackground(Void... params) {
					int i = 0;
					while(i < 10) {
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						i++;
						publishProgress(i + "");
						
					}
					return null;
				}
				
			}.execute(null);
			break;
		}
	}
	
	/**
	 * 自定义线程类,用于测试"Handler为其他线程添加Message"
	 */
	class MyThread extends Thread {

		Handler handler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				System.out.println("received msg with obj:" + msg.obj.toString()); //syso:Thread-1764
			}
		};
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			int i = 0;
			System.out.println(Thread.currentThread().getName());
			while(i < 10) {
				Message msg = new Message();
				msg.obj = i + "";
				handler.sendMessageDelayed(msg, 1000);
				i ++;
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		
		public Handler getHandler() {
			return handler;
		}
	}
}
</span>

           继续抽象类的匿名对象实例化问题,现在加入有一个抽象类A,包含一个抽象方法void methodA。那么采用new A();这种方法实例化A肯定是不行的,Eclipse也会提示我们实现抽象方法的,但是平时我们可能只是按照Eclipse的提示做而已,没有想为什么,我也是这样。只是今天又多想了一下,为什么呢?

           如果我们按照Eclipse的提示采用这样的方法new A() {public void methodA(){ ... } }的方法实例化A的对象。是可以的,因为这种创建对象其实是创建了一个匿名子类的的实例对象,而且该匿名子类又实现了抽象类A中所有的抽象方法,也就是说这个匿名子类不再是一个抽象类,那么当然就可以实例化啦。同样的使用new A();得到的也是匿名子类,不过这个匿名子类没有实现A中的抽象方法,即new A();仍然是一个抽象类,当然不能实例化了。

           O啦~~~

           转帖请保留出处:http://blog.csdn.net/u011638883/article/details/14123755
           谢谢!

                 

         

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值