Android 异步编程

Android的线程和内存模型
Android操作系统在boot后,会启动一个Zygote(受精卵)进程,Zygote进程负责创建大部分应用程序进程。Zygote进程启动 加载核心程序库和数据结构到内存后会创建一个Dalvik虚拟机(DVM)进程--SystemServer,此进程会包含大部分的系统服务(包括管理 Activity的服务ActivityManagerService),SystemServer初始化后,Zygote进程会侦听本地的socket 端口, 等待进一步的指令。当新的app被启动时,Zygote会为这个app创建一个DVM—-直接fork出一个子进程,这种架构的好处是同时启动多个App 时,多个App进程可以访问共享内存。

Android App的进程也是一个DVM,内部有许多线程在执行,比如,主UI线程(Main Thread),垃圾回收线程等。其中主UI线程负责执行我们写的应用代码。对于只做很少的I/O操作或耗时操作的App,单一线程开发模式问题不大,但 是如果有大量IO或者CPU计算的任务,我们就必须在其他线程内完成了。

因为主UI线程需要根据硬件刷新率[^3]同步用户界面的重绘。手机应用体验流畅要求界面帧率[^3]达到每秒60,也就是说每16.67毫秒就需要重绘一帧,这意味着如果我们在主线程上执行的任务超过16毫秒,就会出现丢帧现象,也就是界面会开始变卡。。。

Android异步执行任务的方法有以下几种:

AsyncTask
AsyncTask是最常用的异步方法,功能结构设计的也很丰富,给使用者足够的控制,使用上主要是将异步执行的任务放在下面方法里。

1
protected Result doInBackground(Params... params)
然后调用.execute(params)方法即可。http://www.huiyi8.com/moban/模板

AsyncTask的执行逻辑在API Level 3只能串行执行, 在API Level 4改成了最多128个线程的线程池执行,API Level 11则改成了缺省所有的AsyncTask是在一个线程中顺序执行的,这样可以保证执行和提交的次序一致,如果希望能并发的执行,可以用下面的方法在线程 池内执行:

1
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
AsyncTask.THREAD_POOL_EXECUTOR是ThreadPoolExecutor的一个实例,配置是最少5个线程,最多128个。如果需要自己来配置线程池大小,你可以传递自己配置的一个实例到上述方法。

使用AsyncTask需要注意的几个问题:

碎片化问题
因为不同版本的Android AsyncTask缺省执行逻辑并不一样,可能在不同机型上表现不一致。如果要自己控制AsyncTask的并发度,解决这个问题的建议是复制Android SDK的AsyncTask源码自己实现一个AsyncTask。

Activity生命周期问题
Activity可能早于AsyncTask执行完被销毁,如果AsyncTask还继续执行,有可能会浪费资源,并且如果AsyncTask里引 用了Activity或部分的View Hierarchy,还会造成引用的对象不会被垃圾回收而引起内存泄漏。通常AsyncTask会定义为Activity的一个匿名inner class,这会建立一个隐式的引用到Activity。

解决的方法是:

在Activity里的onPause方法里及时取消不需要再执行的AsyncTask(这种方法在切换到横屏时会重启异步任务,有点浪费)
更好的是使用retained headless fragment来解决生命周期问题,具体演示代码见参考链接
Async比较合适的是较短的(1,2秒),CPU密集计算或读写文件等阻塞IO操作。耗时较长的网络调用用Async不是最合适的。

Handler & HandlerThread
Handler的异步编程是基于消息队列模型的。执行任务的线程称之为Looper线程,其他线程则将需要异步执行的任务发送给Looper线程– 插入其消息队列,方法有:post(较方便使用,但每次需要创建新对象)或sendMessage(较高效,复用消息实例,适合执行大量类似的异步任务)

Looper
Looper和它的名字意思一样就是Looper线程会永远循环,当没有消息的时候,Looper线程(消费者)会使用(Object.wait)方法等待其他线程(生产者)插入新的任务消息,这时候其他线程(Object.notify)

Android的主线程其实就是一个Looper线程。

需要注意的是,使用Handler和AsyncTask一样,要注意匿名inner class对Activity的隐式引用而造成内存泄漏,所以使用的时候要记得清理;

解决方法是使用对使用的Activity中的View对象用Weak Reference,并处理当View对象为null的情况。

Handler适合更长一点的(>2秒)的异步任务处理。

Loader
Loader在Android编程框架中被广泛用于后台加载数据(从文件,数据库甚至网络)。

AsyncTaskLoader
具体的Loader实现。

CursorLoader
用户数据库数据后台加载。

Loader在使用上比较大的优势是和Activity的部分解耦,更见到的生命周期管理。

IntentService
IntentService是Service的一个实现类。其内部实现包含了一个HandlerThread,当任务提交给IntentService时,会被加到队列并顺序处理。

Android 异步编程

时间: 2024-11-12 09:37:05

Android 异步编程的相关文章

Android多线程编程(一)——多线程基础

什么是进程 一个进程是一个独立(self contained)的运行环境,它可以看作一个程序或者一个应用. 什么是线程 而线程是进程中执行的一个任务,Java运行环境是一个包含了不同累和程序的单一进程.线程可以被称为轻量级进程.线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源. Android线程 Android的线程,实际上和Java的多线程编程并没有什么本质上的不同.当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如

异步编程 In .NET

概述 在之前写的一篇关于async和await的前世今生的文章之后,大家似乎在async和await提高网站处理能力方面还有一些疑问,博客园本身也做了不少的尝试.今天我们再来回答一下这个问题,同时我们会做一个async和await在WinForm中的尝试,并且对比在4.5之前的异步编程模式APM/EAP和async/await的区别,最后我们还会探讨在不同线程之间交互的问题. IIS存在着处理能力的问题,但是WinForm却是UI响应的问题,并且WinForm的UI线程至始至终都是同一个,所以两

Android 网络编程 记录

简单介绍 看了深入理解Android网络编程感觉不错.今天对Android网络编程进行了要点记录. 内容 Android基于网络技术和编程实践 要点 定义 描写叙述 IP协议 用于报文交换网络的一种面向数据的协议   TCP协议 传输控制协议,传输层通信协议.   UDP协议 用户数据报协议.传输层协议.   SMTP协议 简单邮件传输协议   SOCKET 套接字 应用层与TCP/IP协议族通信的中间软件抽象层. 类型有两种:TCP套接字和UDP套接字. TCP套接字   在保证可靠性上,採用

Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听

请尊重他人的劳动成果,转载请注明出处: Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听 运行效果图: 我曾在<Android网络编程之使用HttpClient批量上传文件>一文中介绍过如何通过HttpClient实现多文件上传和服务器的接收.在上一篇主要使用Handler+HttpClient的方式实现文件上传.这一篇将介绍使用AsyncTask+HttpClient实现文件上传并监听上传进度. 监控进度实现: 首先

Android多线程编程之线程池学习篇(一)

Android多线程编程之线程池学习篇(一) 一.前言 Android应用开发中多线程编程应用比较广泛,而应用比较多的是ThreadPoolExecutor,AsyncTask,IntentService,HandlerThread,AsyncTaskLoader等,为了更详细的分析每一种实现方式,将单独成篇分析.后续篇章中可能涉及到线程池的知识,特此本篇分析为何使用线程池,如何使用线程池以及线程池的使用原理. 二.Thread Pool基础 进程代表一个运行中的程序,一个运行中的Android

Android 并发编程:(一)基础知识 —— 架构和组件

本章节所有内容皆为原创,如需转载,请注明出处. http://blog.csdn.net/manoel/article/details/38462631 写在前面的话 很久没写博客了,一是因为自身水平有限,怕误人子弟:二是因为感觉没什么可写的:三是因为时间有限,要寻找工作.学习和生活之间的平衡. 最近一直在研究和梳理Android多线程编程的东西,希望能够把这些分享给大家. 想必做过Android应用开发的同学应该都会知道,多线程是一个特别"诡异"的地方.之所以称为"诡异&q

android异步更新UI界面的方法

在android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常,android.view.viewroot$calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views. (只有原始创建这个视图层次(view hierach

Android界面编程——对话框控件(四)

Android界面编程--对话框控件 2.5对话框控件 对话框是提示用户作出决定或输入额外信息的小窗口.对话框不会填充屏幕,通常用于需要用户采取行动才能继续执行的模式事件.Android中常见跟对话框相关控件有Toast.AlertDialog.PopupWindow.ProgressDialog等 2.5.1 Toast Toast用于弹出一个简单文本信息为应用提供反馈,可以和当前活动保持可见和互动,在一定时间后自动消失.Toast有两种形式基本Toast和自定义Toast,效果如图2.5.1

异步编程 In .NET(转)

转自:http://www.cnblogs.com/jesse2013/p/Asynchronous-Programming-In-DotNet.html 概述 在之前写的一篇关于async和await的前世今生的文章之后,大家似乎在async和await提高网站处理能力方面还有一些疑问,博客园本身也做了不少的尝试.今天我们再来回答一下这个问题,同时我们会做一个async和await在WinForm中的尝试,并且对比在4.5之前的异步编程模式APM/EAP和async/await的区别,最后我们