• Android之旅Handler与多线程


          本文首先解释一下handler是用来干嘛的,然后通过例子介绍其在多线程中的应用。

    什么是Handler

         handler通俗一点讲就是用来在各个进程之间发送数据的处理对象。在任何进程中,只要获得了另一个进程的handler则可以通过handler.sendMessage(message)方法向那个进程发送数据。基于这个机制,我们在处理多线程的时候可以新建一个thread,这个thread拥有UI线程中的一个handler。当thread处理完一些耗时的操作后通过传递过来的handler像ui线程发送数据,由UI线程去更新界面。

    handler应用多线程例子

        我们这个例子是实现一个简单的词典功能。在获取网页过程中应用线程。这个程序共有两个activity,第一个用于输入查询的单词,第二个activity用于显示结果。我们直接看第二个activity的内容。(第一个activity无非是获得用户输入的单词然后传给activity2,还没有掌握的可以看我前面的文章)

        首先来看OnCreate:

    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.queryresult);
    
    		tvResult = (TextView) findViewById(R.id.tvResult);
    		String queryString = getIntent().getStringExtra("query");
    
    		Log.d("threadId:", String.valueOf(Thread.currentThread().getId()));
    
    		// 声明一个handler,它的处理程序是实现了callback的类,这里我将这个activity继承了
    		// callback,所以可以传入this。
    		handler = new Handler(this);
    		// 新建一个线程(我们自己实现的线程),将上面的handler和查询的单词传入构造函数
    		GetHtmlThread thread = new GetHtmlThread(handler, getIntent()
    				.getStringExtra("query"));
    		// 开始线程
    		thread.start();
    
    		progressBar = (ProgressBar) findViewById(R.id.prb);
    		progressBar.setVisibility(View.VISIBLE);
    	}

    一些必要的注释我已经在代码注明了。代码中的那个GetHtmlThread线程是继承于Thread的一个类,然后自己实现里面的run方法,这个和c#里面不一样。感觉还是c#里面好理解一点。那我们就看看这个GetHtmlThread类:

    	public class GetHtmlThread extends Thread
    	{
    
    		private Handler handler; // 传入的handler
    		String queryKey; // 要查询的单词
    
    		public GetHtmlThread(Handler handler, String queryKey)
    		{
    			this.handler = handler;
    			this.queryKey = queryKey;
    		}
    
    		@Override
    		public void run() // 线程处理的内容
    		{
    			// 获得网页中关于这个词的解释,返回的网页内容
    			String a = GetTranslateHtml(queryKey);
    
    			// 定义一个消息,用于发给UI线程的handler处理
    			Message msg = new Message();
    			Bundle bundle = new Bundle();
    			// 将查询的结果放进msg中
    			bundle.putString("answer", a);
    			msg.setData(bundle);
    			// 设置这个msg的标识,这样UI中的handler才能根据这个更改对应的UI
    			msg.what = 0;
    			// 将消息发送给UI中的handler处理
    			handler.sendMessage(msg);
    			super.run();
    		}
    	}

    现在线程中的消息发送出去了。我们再到UI线程中处理这个消息。代码如下:

    	/**
    	 * 继承了callback后,必须要实现这个方法。即上面那个handler的处理都在这里进行
    	 */
    	@Override
    	public boolean handleMessage(Message msg)
    	{
    		// 通过判断msg.what来判断到底是哪个"事件"要进行处理
    		switch (msg.what)
    		{
    			case 0:
    				progressBar.setVisibility(View.GONE);
    				// 拿出msg中的数据并显示出来
    				Bundle bundle = msg.getData();
    				tvResult.setText(bundle.getString("answer"));
    				break;
    
    			default:
    				break;
    		}
    		return false;
    	}

    这样我们就可以看到当第二个activity显示一段时间后网页才显示出来,并没有出现卡死的情况!

    最后再来梳理下多线程处理的步骤:

    1

    Demo下载

           Demo下载

  • 相关阅读:
    【Java学习笔记】多线程
    【Java学习笔记】对象生命周期
    【算法实现】插入排序算法
    【Java学习笔记】修饰符
    伍迷创意随想集 之 聚众广告创精品
    《软件观念革命——交互设计精髓》读书笔记(一)
    《交互设计之路——让高科技产品回归人性》读书笔记(七)
    《交互设计之路——让高科技产品回归人性》读书笔记(一)
    伍迷创意随想集
    《软件观念革命——交互设计精髓》读书笔记(三)
  • 原文地址:https://www.cnblogs.com/qianlifeng/p/1903415.html
Copyright © 2020-2023  润新知