android多线程讲解 看图理解.doc_第1页
android多线程讲解 看图理解.doc_第2页
android多线程讲解 看图理解.doc_第3页
android多线程讲解 看图理解.doc_第4页
android多线程讲解 看图理解.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本期的多线程主题与Android相关,侧重讲解在Android中如何用好多线程,需要你有Java的多线程基础。首先我们思考几个问题,在Android应用中为什么要用多线程?为了解决哪些问题?或者为了实现哪些功能?有哪些好处?请先思考一分钟,再继续往下看。学习而不思考就像吃东西而不嚼,要么无法下咽,要么尝不出味道,同时都会影响消化吸收。控制一下你那脱缰野马一样的好奇心吧,先思考再往下看。飘过这条分隔线,我们继续1.为什么要用多线程这里列出几个原因:a) 提高用户体验或者避免ANR在事件处理代码中需要使用多线程,否则会出现ANR(Application is not responding),或者因为响应较慢导致用户体验很差。图1 ANR对话框b) 异步应用中有些情况下并不一定需要同步阻塞去等待返回结果,可以通过多线程来实现异步,例如:上一点中提到的,你的应用中的某个Activity需要从云端获取一些图片,加载图片比较耗时,这时需要使用异步加载,加载完成一个图片刷新一个,见下面图2、图3 。c) 多任务例如多线程下载。后两点与Java中的多线程应用没有太大区别,不细说。下面重点说明第一点,即如何减少事件响应的时间从而提高用户体验,以及如何避免ANR。2.为什么通过多线程可以提高用户体验、避免ANR大家还记得我在群里说过的移动开发的“三不要”原则吗?即:不要让我想、不要让我等、不要让我烦。响应慢了用户需要等,等的次数多了就会烦,你的应用离被卸载不远了。首先我们来了解一下Android应用程序的main线程,它负责处理UI的绘制,Android系统为了防止应用程序反应较慢导致系统无法正常运行做了一个处理,一种情况是当用户输入事件在5秒内无法得到响应,那么系统会弹出ANR对话框,由用户决定继续等待还是强制结束应用程序(另一种情况是BroadcastReciever 超过10秒没执行完也会弹出ANR对话框)。即使你的程序中某个事件响应不超过5秒钟,人眼可以分辨的时间是0.1秒,小于0.1秒基本感觉不出来,超过0.2秒用户就能感觉到有点儿卡了,俗称打嗝现象,2秒以上就很慢了,用户体验会很差。有同学说我可以用进度条啊,但你的程序中不能到处都是进度条,否则那个圈圈会把用户转晕的,好像在对用户说,画个圈圈烦死你比如某些应用,它要显示很多图片,还好它是异步的,不过在图片加载完成前每个图片的位置上都有一个圈圈,让人看了很烦。你可以变通一下,图片加载成功之前显示一个默认的图片,加载成功后再刷新一下即可,何必弄那么多进度条呢?图2 加载图片完成前显示默认图片,加载完成后再刷新图3 加载图片完成前显示默认图片,加载完成后再刷新图4 转晕你,烦死你事件处理的原则:所有可能耗时的操作都放到其他线程去处理。Android中的Main线程的事件处理不能太耗时,否则后续的事件无法在5秒内得到响应,就会弹出ANR对话框。那么哪些方法会在 Main线程执行呢?1) Activity的生命周期方法,例如:onCreate()、onStart()、onResume()等2) 事件处理方法,例如onClick()、onItemClick()等通常Android基类中以on开头的方法是在Main线程被回调的。提高应用的响应性,可以从这两方面入手。一般来说,Activity的onCreate()、onStart()、onResume()方法的执行时间决定了你的应用首页打开的时间,这里要尽量把不必要的操作放到其他线程去处理,如果仍然很耗时,可以使用SplashScreen。使用SplashScreen最好用动态的,这样用户知道你的应用没有死掉。图5 动态SplashScreen图6 静态SplashScreen当用户与你的应用交互时,事件处理方法的执行快慢决定了应用的响应性是否良好,这里分两种情况:1) 同步,需要等待返回结果。例如用户点击了注册按钮,需要等待服务端返回结果,那么需要有一个进度条来提示用户你的程序正在运行没有死掉。一般与服务端交互的都要有进度条,例如系统自带的浏览器,URL跳转时会有进度条。2) 异步,不需要等待返回结果。例如微博中的收藏功能,点击完收藏按钮后是否成功执行完成后告诉我就行了,我不想等它,这里最好实现为异步的。无论同步异步,事件处理都可能比较耗时,那么需要放到其他线程中处理,等处理完成后,再通知界面刷新。这里有一点要注意,不是所有的界面刷新行为都需要放到Main线程处理,例如TextView的setText()方法需要在Main线程中,否则会抛出CalledFromWrongThreadException,而ProgressBar的setProgress()方法则不需要在Main线程中处理。当然你也可以把所有UI组件相关行为都放到Main线程中处理,没有问题。可以减轻你的思考负担,但你最好了解他们之间的差别,掌握事物之间细微差别的是专家。把事件处理代码放到其他线程中处理,如果处理的结果需要刷新界面,那么需要线程间通讯的方法来实现在其他线程中发消息给Main线程处理。3.如何实现线程间通讯在Android中有多种方法可以实现其他线程与Main线程通讯,我们这里介绍常见的两种。1) 使用AsyncTaskAsyncTask是Android框架提供的异步处理的辅助类,它可以实现耗时操作在其他线程执行,而处理结果在Main线程执行,对于开发者而言,它屏蔽掉了多线程和后面要讲的Handler的概念。你不了解怎么处理线程间通讯也没有关系,AsyncTask体贴的帮你做好了。不过封装越好越高级的API,对初级程序员反而越不利,就是你不了解它的原理。当你需要面对更加复杂的情况,而高级API无法完成得很好时,你就杯具了。所以,我们也要掌握功能更强大,更自由的与Main线程通讯的方法:Handler的使用。2) 使用Handler这里需要了解Android SDK提供的几个线程间通讯的类。2.1 HandlerHandler在android里负责发送和处理消息,通过它可以实现其他线程与Main线程之间的消息通讯。2.2 LooperLooper负责管理线程的消息队列和消息循环2.3 MessageMessage是线程间通讯的消息载体。两个码头之间运输货物,Message充当集装箱的功能,里面可以存放任何你想要传递的消息。2.4 MessageQueueMessageQueue是消息队列,先进先出,它的作用是保存有待线程处理的消息。它们四者之间的关系是,在其他线程中调用Handler.sendMsg()方法(参数是Message对象),将需要Main线程处理的事件添加到Main线程的MessageQueue中,Main线程通过MainLooper从消息队列中取出Handler发过来的这个消息时,会回调Handler的handlerMessage()方法。除了以上两种常用方法之外,还有几种比较简单的方法3) Activity.runOnUiThread(Runnable)4) View.post(Runnable)View.postDelayed(Runnable, long)5) Handler.postHandler.postDelayed(Runnable, long)4.利用线程池提高性能这里我们建议使用线程池来管理临时的Thread对象,从而达到提高应用程序性能的目的。线程池是资源池在线程应用中的一个实例。了解线程池之前我们首先要了解一下资源池的概念。在JAVA中,创建和销毁对象是比较消耗资源的。我们如果在应用中需要频繁创建销毁某个类型的对象实

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论