博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程:使用Thread和Handler
阅读量:6329 次
发布时间:2019-06-22

本文共 3774 字,大约阅读时间需要 12 分钟。

hot3.png

当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。 

比如说从网上获取一个图片,在一个ImageView中将其显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得图片后,是不能直接在网络操作线程中调用ImageView的相关方法的,因为其他线程中是不能直接访问主UI线程成员 。

非UI线程发送消息到UI线程分为两个步骤

一、发送消息到UI线程的消息队列

通过使用Handler的

Message obtainMessage(int what,Object object)

构造一个Message对象,这个对象存储了是否成功获取图片的标识what和bitmap对象,然后通过message.sendToTarget()方法把这条message放到消息队列中去。

二、处理发送到UI线程的消息

在UI线程中,我们覆盖了handler的

public void handleMessage (Message msg)

这个方法是处理分发给UI线程的消息,判断msg.what的值可以知道mThread是否成功获取图片,如果图片成功获取,那么可以通过msg.obj获取到这个对象。

最后,我们通过

mImageView.setImageBitmap((Bitmap) msg.obj);

设置ImageView的bitmap对象,完成UI的更新。

补充:

事实上,我们还可以调用

View的post方法来更新UI

mImageView.post(new Runnable() {//另外一种更简洁的发送消息给UI线程的方法。                                    @Override                  public void run() {//run()方法会在UI线程执行                      mImageView.setImageBitmap(bm);                  }              });

这种方法会把Runnable对象发送到消息队列,UI线程接收到消息后会执行这个runnable对象。

完整代码:

注意的是:Manifest.xml文件中,要声明网络权限。

package com.xsjayz.thread;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import android.app.Activity;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.Toast;/** * 使用Thread+Handler的方式实现在非UI线程发送消息通知UI线程更新界面 *  *   XuShaoJie * @version 2012-08-31 */public class ThreadHandlerActivity extends Activity {	private static final int MSG_SUCCESS = 0;// 获取图片成功的标识	private static final int MSG_FAILURE = 1;// 获取图片失败的标识	private ImageView mImageView;	private Button mButton;	private Thread mThread;	@Override	public void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.main);		mImageView = (ImageView) findViewById(R.id.imageView);		mButton = (Button) findViewById(R.id.button);		mButton.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View v) {				// 如果线程还没启动,则启动新的线程				if (mThread == null) {					mThread = new Thread(runnable);					mThread.start();					// 否则提示:"线程已经启动"				} else {					Toast.makeText(							getApplication(),							getApplication().getString(R.string.thread_started),							Toast.LENGTH_LONG).show();				}			}		});	}	private Handler mHandler = new Handler() {		// 重写handleMessage()方法,此方法在UI线程运行		@Override		public void handleMessage(Message msg) {			switch (msg.what) {			// 如果成功,则显示从网络获取到的图片			case MSG_SUCCESS:				mImageView.setImageBitmap((Bitmap) msg.obj);				Toast.makeText(getApplication(),						getApplication().getString(R.string.get_pic_success),						Toast.LENGTH_LONG).show();				break;			// 否则提示失败			case MSG_FAILURE:				Toast.makeText(getApplication(),						getApplication().getString(R.string.get_pic_failure),						Toast.LENGTH_LONG).show();				break;			}		}	};	Runnable runnable = new Runnable() {		// 重写run()方法,此方法在新的线程中运行		@Override		public void run() {			HttpClient httpClient = new DefaultHttpClient();			// 从网络上获取图片			HttpGet httpGet = new HttpGet(					"http://www.oschina.net/img/logo.gif");			final Bitmap bitmap;			try {				HttpResponse httpResponse = httpClient.execute(httpGet);				// 解析为图片				bitmap = BitmapFactory.decodeStream(httpResponse.getEntity()						.getContent());			} catch (Exception e) {				mHandler.obtainMessage(MSG_FAILURE).sendToTarget();// 获取图片失败				return;			}			// 获取图片成功,向UI线程发送MSG_SUCCESS标识和bitmap对象			mHandler.obtainMessage(MSG_SUCCESS, bitmap).sendToTarget();		}	};}

转载于:https://my.oschina.net/xsjayz/blog/75892

你可能感兴趣的文章
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(2)
查看>>
Lync 小技巧-5-当前已暂停共享
查看>>
无线802.11n 2.4G与5G性能测试
查看>>
子域名信息收集攻略
查看>>
[Android]开发数独游戏思路分析过程
查看>>
SpreadJS 类Excel表格控件 - V12 新特性详解
查看>>
理解并取证:IPv6与IPv4在报文结构上的区别
查看>>
EOS主网上线只是开始,如何运营决定未来
查看>>
不用Visual Studio,5分钟轻松实现一张报表
查看>>
(译)如何使用cocos2d和box2d来制作一个Breakout游戏:第一部分
查看>>
敬告各位 ALinq 用户,切勿上当受骗
查看>>
计算机图形学(一) 图形系统综述
查看>>
持续集成(CI)- 几种测试的区别(摘录)
查看>>
多用户虚拟Web3D环境Deep MatrixIP9 1.04发布
查看>>
求高手,求解释
查看>>
[MSSQL]NTILE另类分页有么有?!
查看>>
winform datagridview 通过弹出小窗口来隐藏列 和冻结窗口
查看>>
C机顶盒开发实战常用初始化类型:数组、结构、指针
查看>>
Jquery闪烁提示特效
查看>>
最佳6款用于移动网站开发的 jQuery 图片滑块插件
查看>>