【Android】Android中的线程(Thread+Handler)

之前po了一篇文章:【Android】Android中的线程(AsyncTask),现在说说Android中实现多线程的另一种方法Thread+Handler,博主这种方法用得不多,主要通过这篇文章学习Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面,再次特别感谢这篇文章的博主。

 

Thread+Handler

要通过Thread实现多线程,通常先写一个类继承Runnable,实现run()方法,在里面做子线程要执行的任务。在博主上篇文章里写到过“不能在UI Thread之外的线程当中操纵UI元素”,如果子线程需要更改UI,就要借助Handler实现:写一个类继承Handler,实现handleMessage(Message)方法,这个方法运行在UI Thread中。在子线程的run()方法中,调用handler.sendMessage()方法将一些数据信息传给Handler,handleMessage(Message)根据不同数据做出不同处理,更改UI。

Thread+Handler与AsyncTask的对比

在网上查了一些探讨这两种方法的文章,因为博主目前用到多线程的地方都比较简单,这些文章中的有些代码没有实验,仅在这里mark下来,以备不时之需。

1. Android多线程任务优化1:探讨AsyncTask的缺陷:这篇文章中博主通过一个例子说明了,当新开大量线程时,AsyncTask可能存在消耗系统资源、导致应用FC的风险,因此需要我们根据自己的需求自定义不同的线程池。在Android多线程任务优化2:实现后台预读线程这篇文章里给出了解决办法。

2. 深入解析AsyncTask:这篇文章中博主给出了一些使用选择Thread+Handler/AsyncTask的建议,并且给出了自己的代码参考。

  • 改善你的设计,少用异步处理:线程的开销是非常大的,同时异步处理也容易出错,难调试,难维护,所以改善你的设计,尽可能的少用异步。对于一般性的数据库查询,少量的I/O操作是没有必要启动线程的。
  • 如果不与主线程通信,就用ThreadAsyncTask被设计出来的目的就是为了满足Android的特殊需求:非主线程不能操作(UI)组件,所以AsyncTask扩展Thread增强了与主线程的交互的能力。如果你的应用没有与主线程交互,那么就直接使用Thread就好了。
  • 当有需要大量线程执行任务时,一定要创建线程池:线程的开销是非常大的,特别是创建一个新线程,否则就不必设计线程池之类的工具了。当需要大量线程执行任务时,一定要创建线程池,无论是使用AsyncTask还是Thread,因为使用AsyncTask它内部的线程池有数量限制,可能无法满足需求;使用Thread更是要线程池来管理,避免虚拟机创建大量的线程。比如从网络上批量下载图片,你不想一个一个的下,或者5个5个的下载,那么就创建一个CorePoolSize为10或者20的线程池,每次10个或者20个这样的下载,即满足了速度,又不至于耗费无用的性能开销去无限制的创建线程。
  • 对于想要立即开始执行的异步任务,要么直接使用Thread,要么单独创建线程池提供给AsyncTask:默认的AsyncTask不一定会立即执行你的任务,除非你提供给他一个单独的线程池。如果不与主线程交互,直接创建一个Thread就可以了,虽然创建线程开销比较大,但如果这不是批量操作就没有问题。

下面以博主最近自己在写的一个程序为例,po一下使用Thread+Handler的基本代码。

=====================================华丽丽的分割线===================================

功能描述:

与博主上一篇文章一样,某个Activity需要解析xml文件,并将解析结果展示在界面上,解析xml的工作比较耗时,需要在Worker Thread中执行。

具体分析:

  • run():中解析出想要的xml信息,将该信息通过handler.sendMessage()方法传给Handler。
  • handleMessage(Message):根据传来的的信息修改UI界面。

根据以上分析,首先在Activity里增加一个继承Runnable的类和一个继承Handler的类。

/**
 * 解析xml文件的线程
 */
private class PaperRunnable implements Runnable
{
	private PaperParser parser;
	private FileInputStream in;
	
	private PaperRunnable(String file)
	{//初始化一些相关变量
		......
	}
	
	@Override
	public void run()
	{
		String stringTemp="";
		for(int i=numOfPaper;i>0&&mRunning==true;i--)
		{
			stringTemp=parser.queryThePaper(i);
			//将解析出的数据传给Handler,MSG_PAP是标志数据种类的静态变量
			ppHandler.obtainMessage(MSG_PAP,i+"@@"+stringTemp).sendToTarget();
		}	
		try
		{
			in.close();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}
}

/**
 * 处理xml解析结果的Handler
 */
private class PaperHandler extends Handler
{
	@Override
	public void handleMessage (Message msg)
	{//此方法在UI线程运行
		switch(msg.what)
		{
			case MSG_PAP://对于标志了MSG_PAP的数据进行下面的处理
				//addPaper是将字符串显示在界面上的方法
				addPaper(((String)msg.obj).split("@@"));
				break;
		}
	}
}

要开启子线程,先要在Activity中声明两个变量

private ThreadmThread;
privatePaperRunnable ppRunnable==new PaperHandler();

开启线程时

if(mThread==null)
{
          ppRunnable=newPaperRunnable(auth+".xml");
          mThread = new Thread(ppRunnable);
          mThread.start();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值