AsnyncTask与handler(二)——handler消息机制

前言:继上篇,上篇中实现了AsyncTask异步加载图片,在文章最后,我们抛出了个问题:“如果想在doInBackground()中更新UI怎么办”这篇文章就是解决这个问题的,本篇程序建立在上篇基础之上,在看本篇之前,请先移步上篇《AsnyncTask与handler(一)——AsyncTask异步处理

相关文章:《AsnyncTask与handler(一)——AsyncTask异步处理


有关hander.postDelayed()的一个重要问题是:《销毁activity时注意关闭线程》,不然可能会造成activity已经销毁,而postDelayed的线程过段时间又运行,产生错误!!

一、handler消息机制

Handler一般有两种用途:1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器。2)线程间通信。在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息。当你创建子线程时,你可以再你的子线程中拿到父线程中创建的Handler对象,就可以通过该对象向父线程的消息队列发送消息了。由于Android要求在UI线程中更新界面,因此,可以通过该方法在其它线程中更新界面。

使用handler机制的方法:
1、新建一个handler类来处理主线程中的UI更新问题

private class MyHandler extends Handler{   
	 @Override
     public void handleMessage(Message msg) {//处理消息
		 
		 switch (msg.what) {
		case 1:
			String str=(String) msg.obj;
			
			Toast.makeText(getApplicationContext(),str, Toast.LENGTH_SHORT).show();
			break;
		default:
			break;
		}
     } 
}

2、定义变量与赋值
定义一个变量Handler m_mainHandler;然后在OnCreate()函数中对其初始化:m_mainHandler=new MyHandler();

3、发送消息

Message msg=new Message();
msg.what=1;
msg.obj="传回图片了";
m_mainHandler.sendMessage(msg); //发送消息更新UI

二、实例

在上篇的基础上,在doInBackground()中利用handler发送消息,使其发出Toast消息提示---“传回照片了”。

总体效果为:


XML没变,JAVA代码如下:

package com.example.try_asynctask_handler;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;

public class MainActivity extends Activity {

	private ImageView	image		= null;
	private Button		show;
	private ProgressBar	progressBar	= null;
	private int			number		= 0;
	List<String>		imageUrl	= null;
	
	Handler m_mainHandler;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		m_mainHandler=new MyHandler();
		
		progressBar = (ProgressBar) findViewById(R.id.processBar);
		image = (ImageView) findViewById(R.id.image);
		show = (Button) findViewById(R.id.show);
		show.setOnClickListener(new showButtonListener());
		
		imageUrl = new ArrayList<String>(); // 图片地址List
		imageUrl.add("http://image.tianjimedia.com/uploadImages/2011/266/AIO90AV2508S.jpg");
		imageUrl.add("http://image.tianjimedia.com/uploadImages/2012/090/063N2L5N2HID.jpg");
		imageUrl.add("http://comic.sinaimg.cn/2011/0824/U5237P1157DT20110824161051.jpg");
		imageUrl.add("http://image.tianjimedia.com/uploadImages/2012/090/1429QO6389U8.jpg");
		imageUrl.add("http://new.aliyiyao.com/UpFiles/Image/2011/01/13/nc_129393721364387442.jpg");
	}

	public class showButtonListener implements OnClickListener
	{
		@Override
		public void onClick(View v)
		{
			number++;
			MyAsyncTask myAsyncTask = new MyAsyncTask(getApplicationContext());
			myAsyncTask.execute(imageUrl.get(number % 5));
		}
	}
	
	class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>
	{
		// 可变长的输入参数,与AsyncTask.exucute()对应
		public MyAsyncTask(Context context)
		{
			progressBar.setVisibility(View.VISIBLE);
			image.setVisibility(View.GONE);
		}
		@Override
		protected Bitmap doInBackground(String... params)
		{
			Bitmap bitmap = null;
			try
			{
				//根据URL取得图片并返回 
                URL url = new URL(params[0]);  
                
                URLConnection conn = url.openConnection();  
                conn.connect();  
                InputStream inputStream = conn.getInputStream();  
                bitmap = BitmapFactory.decodeStream(inputStream);  
                
                Message msg=new Message();
                msg.what=1;
                msg.obj="传回图片了";
                m_mainHandler.sendMessage(msg); //发送消息更新UI
                
//				Toast.makeText(getApplicationContext(), "传回图片了", Toast.LENGTH_SHORT).show();
				inputStream.close();
			}
			catch (Exception e)
			{
				Log.e("msg", e.getMessage());
			}
			return bitmap;
		}

		/**
		 * 在doInBackground 执行完成后,onPostExecute方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
		 */
		@Override
		protected void onPostExecute(Bitmap bitmap)
		{
			progressBar.setVisibility(View.GONE);
			image.setVisibility(View.VISIBLE);
			if (bitmap != null)
			{
				image.setImageBitmap(bitmap);
			}
			else
			{
				Toast.makeText(getApplicationContext(), "网络异常", Toast.LENGTH_SHORT).show();
			}
		}

		/**
		 * 该方法将在执行实际的后台操作前被UI thread调用。这个方法只是做一些准备工作,如在界面上显示一个进度条。
		 */
		@Override
		protected void onPreExecute()
		{
			// 任务启动
			Toast.makeText(getApplicationContext(), "任务开始......", Toast.LENGTH_SHORT).show();
		}
	}
	
	/**
	 * 新建一个handler类来处理主线程中的UI更新问题
	 * @author Administrator
	 *
	 */
	private class MyHandler extends Handler{   
		 @Override
         public void handleMessage(Message msg) {//处理消息
			 
			 switch (msg.what) {
			case 1:
				String str=(String) msg.obj;
				
				Toast.makeText(getApplicationContext(),str, Toast.LENGTH_SHORT).show();
				break;
			default:
				break;
			}
         } 
	}

}

根据上面的使用handler步骤写出以后代码难度不大,这里就不再详细讲解了。

其它

1、handler的另一用法

1、在主线程中创建

m_mianhandler=new Handler();

2、用的时候:

	private void promptAlertDialog()
	{
		 m_mainHandler.post(new Runnable() {
	            public void run() {
			…… 
	            }
	        });
	}

这一用法部分相关文章:

《Android--多线程之Handler》:http://www.cnblogs.com/plokmju/p/android_handler.html
 




源码地址:http://download.csdn.net/detail/harvic880925/7275431 ,不要分,仅供分享


请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/24783459,不胜感激!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值