Android异步加载方案

Android的Lazy Load主要体现在网络数据(图片)异步加载、数据库 查询、复杂业务逻辑处理以及费时任务操作导致的异步处理等方面。在介绍Android开发过程中,异步处理这个常见的技术问题之前,我们简单回顾下Android开发过程中需要注意的几个地方。
Android应用开发过程中必须遵循单线程模型(Single Thread Model)的原则。因为Android的UI操作并不是线程安全的,所以涉及UI的操作必须在UI线程中完成。但是并非所有的操作都能在主线程中进行,Google工程师在设计上约定,Android应用在5s内无响应的话会导致ANR(Application Not Response),这就要求开发者必须遵循两条法则:1、不能阻塞UI线程,2、确保只在UI线程中访问Android UI工具包。于是,开启子线程进行异步处理的技术方案应运而生。
一、 AsyncTask(异步任务)
AsyncTask的特点是任务运行在主线程之外,二回调方法是运行在主线程中,这就有效地避免了Handler带来的麻烦,AsyncTask定义了三种泛型类型,Params、Progress、和Result。Params是执行任务输入的参数,比如Http请求的URL,Progress为后台执行任务的百分比,Result是后台执行任务返回的结果,子类必须实现抽象方法。这些方法由AsyncTask在执行任务不同时期调用,向外传递任务执行情况。
doInBackground(Params… p): 在此方法中实现任务的执行工作,比如连接网络获取数据等。
onPostExecute(Result r): 此方法在主线程执行,任务执行的结果作为此方法的参数返回。   
publicProgress(Progress…):外部调用更新任务进度方法
onProgressUpdate(Progress…) :通知外部进度已更新 网上例子很多,这里就不赘述了

二、Handler+Thread+Message模式

该模式的核心思想是在耗时方法中(例如网络请求)new Thread()创建线程,在线程的run方法中进行耗时操作,调用thread.start()开启线程。这样就实现了异步(没有在主线程中进行耗时操作),操作得到结果后,将结果封装为message,通过Handler线程间通信发送给主线程,主线程拿到结果。这也是最常用的模式。比较熟悉,不贴出代码


三、Handler+ExecutorService(线程池)+MessageQueue模式

能开启的线程数总是有限的,此时我们使用线程池,线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程调度由池管理器管理,当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。

四、使用IntentService

IntentService是一个基于Service的一个类,用来处理异步的请求。你可以通过startService(Intent)来提交请求,该Service会在需要的时候创建,当完成所有的任务以后自己关闭,且请求是在工作线程处理的。
客户端可以通过startService(Intent)方法传递请求给IntentService。IntentService在onCreate()函数中通过HandlerThread单独开启一个线程来处理所有Intent请求对象(通过startService的方式发送过来的)所对应的任务,这样以免事务处理阻塞主线程。执行完所一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service;否则执行下一个Intent请求所对应的任务。
IntentService在处理事务时,还是采用的Handler方式,创建一个名叫ServiceHandler的内部Handler,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理一个intent所对应的事务都封装到叫做onHandleIntent的虚函数;因此我们直接实现虚函数onHandleIntent,再在里面根据Intent的不同进行不同的事务处理就可以了。示例:

五、使用HandlerThread

HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper.
HandlerThread 继承自Thread,内部封装了Looper。
首先Handler和HandlerThread的主要区别是:Handler与Activity在同一个线程中,HandlerThread与Activity不在同一个线程,而是别外新的线程中(Handler中不能做耗时的操作)。
handlerthread的常规用法
1、创建handlerthread线程,参数代表线程名。priority代表优先级。优先级范围为-20到19,默认为0,优先级越高,获得的CPU资源更多,反之则越少。-20代表优先级最高,反之19最低。
mThread = new HandlerThread("handler_thread"); mThread.start();
2、创建处理耗时任务的子线程handler和处理UI的UIHandler
在创建子任务handler时与handlerthread的Looper关联,这样,这个handler就是运行在子线程中的,在该handler的handleMessage(Message msg)方法中处理耗时任务,处理后通知UIHandler更新UI
在合适的时机退出handlerthread,比如activity的onDestory()中,方法有quit()和quitSafely();

示例:



在update方法中进行了数据的更新以及向主线程发送消息。之后判断是否接着更新,若更新,继续向子线程handler发送消息,再次走到mThreadHandler.handlerMessage()中更新,下面是update方法

向主线程发消息,此时也就是告诉主线程要执行的任务

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值