Android多线程更新UI的方式

Android下,对于耗时的操作要放到子线程中,要不然会残生ANR,本次我们就来学习一下Android多线程更新UI的方式。

  首先我们来认识一下anr:

  anr:application not reponse:应用程序无响应
  主线程:UI线程
  anr产生的原因:主线程需要做很多重要的事情,响应点击事件,更新ui,如果在主线程里面阻塞时间过久,应用程序就会无响应,为了避免应用程序出现anr,所有的耗时的操作,都应该放在子线程中执行。

  认识了anr后,我们就来学习一下怎样在Android下开启多线程,并更新ui了。一共有两种方式:

第一种采用:Handler。

  Handler获取当前线程中的looper对象,looper用来从存有Message的Message Queue里取出message,再由Handler进行message的分发和处理。

handler进制的原理

  android提供了handler和looper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange).

     1)looper:一个线程可以产生一个looper对象,由它来管理此线程里的message queue(消息队列)

      2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。

我们使用的时候呢,需要在子线程中定义message,并把要返回的obj对象,传递给msg,同时由于handler不止要处理这一种类型,所以我们还要定义what的类型,以便让handler分类处理。

	Message msg = new Message();

	msg.what = CHANGE_UI;

	msg.obj = result;

	handler.sendMessage(msg);

 

好的接下来我们就实例来使用handler。

		   new Thread(){

			   public void run() {

				   try {

					URL url = new URL(path);

					HttpURLConnection conn = (HttpURLConnection) url.openConnection();

					conn.setRequestMethod("GET");

					conn.setConnectTimeout(5000);

					conn.setRequestProperty("User-Agent", "");

					

					int code = conn.getResponseCode();

					if(code==200){

						InputStream is = conn.getInputStream();

						String result = StreamTools.readInputStream(is);

						

						//tv_content.setText(result);

						Message msg = new Message();

						msg.what = CHANGE_UI;

						msg.obj = result;

						handler.sendMessage(msg);

						

						

					}else{

						Message msg = new Message();

						msg.what = ERROR;

						handler.sendMessage(msg);

					}

					

				} catch (Exception e) {

					// TODO Auto-generated catch block

					e.printStackTrace();

					

					Message msg = new Message();

					msg.what = ERROR;

					handler.sendMessage(msg);

					

					

				}

				   

				   

			   };

		   }.start();

 这里采用的 StreamTools.readInputStream的实现是这样的,目的是把输入流转化为字符串。

/**

	 * 把输入流转化为字符串

	 * @param is

	 * @return

	 */

	public static String readInputStream(InputStream is){

		try {

			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			int len = 0;

			byte[] buffer = new byte[1024];

			while((len = is.read(buffer))!=-1){

				baos.write(buffer,0,len);

			}

			is.close();

			baos.close();

			byte[] result = baos.toByteArray();

			

			//试着解析网址返回的字符串,

			String temp = new String(result);

			if(temp.contains("utf-8")){

				return temp;

			}else if(temp.contains("gbk")){

				return new String(result,"gbk");

			}

			

			return temp;

			//return new String(result);

		} catch (Exception e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

			return "获取失败";

		}

		

	}

 

其中handler的实现是这样的。

	

	private Handler handler = new Handler(){

		public void handleMessage(android.os.Message msg) {

			switch (msg.what) {

			case ERROR:

				Toast.makeText(MainActivity.this, "获取数据失败", 0).show();

				break;

			case CHANGE_UI:

				tv_content.setText(msg.obj+"");

				Toast.makeText(MainActivity.this, "获取数据失败", 0).show();

				break;



			}

		};

	};

 这样呢,我们便可以用handler,也即消息处理机制来更新UI了,

 

第二种方式。

  采用runOnUiThread(new Runnable()),这要实现Runnable借口,我们可以直接在这个线程中进行UI的更新。是api提供的方法,较为便捷。

  

	new Thread(){

    		@Override

    		public void run() {

    			final String result = LoginServices.loginByGet(username, password);

    			if(result != null){

    				//成功

    				runOnUiThread(new Runnable() {

						

						@Override

						public void run() {

							// TODO Auto-generated method stub

							Toast.makeText(MainActivity.this, result, 0).show();

						}

					});

    			}else{

    				//请求失败

    				runOnUiThread(new Runnable() {

						

						@Override

						public void run() {

							// TODO Auto-generated method stub

							Toast.makeText(MainActivity.this, "请求失败", 0).show();

						}

					});

    			}

    			

    		};

    	}.start();

 

源码:https://github.com/darren90/ChengeUI

 

作者:Darren

微博:@IT_攻城师

出处:http://www.cnblogs.com/fengtengfei/

 

 

  

你可能感兴趣的:(android)