- 浏览: 1076777 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (202)
- Android (31)
- Eclipse 使用 (14)
- 笔记 (5)
- 杂七杂八 (3)
- Java (18)
- 数据库 (6)
- web (21)
- JavaScript (24)
- Http (1)
- 杂谈 (1)
- JSP & Servlet (5)
- log4j (1)
- Linux (13)
- MS Office (3)
- postgresql (7)
- Tomcat (5)
- windows (4)
- tmp (1)
- Perl (1)
- Struts2 (17)
- JQuery (5)
- HTML5 (3)
- JSLint (2)
- iphone (1)
- ant (2)
- IE (1)
- tcp (1)
- JBoss (4)
- 正则表达式 (2)
- jmeter (1)
- CI (1)
- sonarqube (1)
- junit (1)
- chrome (1)
- mybatis (2)
- mysql (3)
- spring (2)
- maven (1)
最新评论
-
天使建站:
看这里:jquery里和操作数组的相关的:$.merg ...
JQuery 数组 -
lgywindows:
我照你的方法实现了在java中取国际化。谢谢提供!
spring mvc中,如何在 Java 代码里,获取 国际化 内容 -
ylhkaixin:
请教下大神,我转换报告的时候报错:report: [x ...
通过ant来批量执行jmeter脚本,并生成报告(附: 生成报告时报“Content is not allowed in prolog”这个错误的解决方案) -
lemon_yt:
正在找
spring mvc中,如何在 Java 代码里,获取 国际化 内容 -
Rainbow702:
alike222 写道Rainbow702 写道MyDream ...
通过ant来批量执行jmeter脚本,并生成报告(附: 生成报告时报“Content is not allowed in prolog”这个错误的解决方案)
当第一次启动一个Android程序时,Android会自动创建一个称为“main”主线程的线程。这个主线程(也称为UI线程)很重要,因为它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与Andriod控件交互的线程。比如,当你在屏幕上按下一个按钮后,UI线程会把这个事件分发给刚按得那个按钮,紧接着按钮设置它自身为被按下状态并向事件队列发送一个无效(invalidate)请求。UI线程会把这个请求移出事件队列并通知按钮在屏幕上重新绘制自身。
单线程模型会在没有考虑到它的影响的情况下引起Android应用程序性能低下,因为所有的任务都在同一个线程中执行,如果执行一些耗时的操作,如访问网络或查询数据库,会阻塞整个用户界面。当在执行一些耗时的操作的时候,不能及时地分发事件,包括用户界面重绘事件。从用户的角度来看,应用程序看上去像挂掉了。更糟糕的是,如果阻塞应用程序的时间过长(现在大概是5秒钟)Android会向用户提示一些信息,即打开一个“应用程序没有相应(application not responding)”的对话框。
如果你想知道这有多糟糕,写一个简单的含有一个按钮的程序,并为按钮注册一个单击事件,并在事件处理器中调用这样的代码 Thread.sleep(2000)。在按下这个按钮这后恢复按钮的正常状态之前,它会保持按下状态大概2秒钟。如果这样的情况在你编写的应用程序中发生,用户的第一反应就是你的程序运行很慢。
现在你知道你应该避免在UI线程中执行耗时的操作,你很有可能会在后台线程或工作者线程中执行这些耗时的任务,这样做是否正确呢?让我们来看一个例子,在这个例子中按钮的单击事件从网络上下载一副图片并使用ImageView来展现这幅图片。代码如下:
public void onClick( View v ) { new Thread( new Runnable() { public void run() { Bitmap b = loadImageFromNetwork(); mImageView.setImageBitmap( b ); } }).start(); }
这段代码好像很好地解决了你遇到的问题,因为它不会阻塞UI线程。很不幸,它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在这段代码片段中,在一个工作者线程中使用ImageView的方法,这回引起一些很古怪的问题。查处这个问题并修复这个bug会很困难而且也很耗时。
Andriod提供了几种在其他线程中访问UI线程的方法。或许你已经对其中的一些方式很熟悉,但下面是一个更全面的列表:
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable, long )
Hanlder
上面的任何一个类或方法都可以修复我们前面代码中出现的问题。
public void onClick( View v ) { new Thread( new Runnable() { public void run() { final Bitmap b = loadImageFromNetwork(); mImageView.post( new Runnable() { mImageView.setImageBitmap( b ); }); } }).start(); }
很不幸的是这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。
在Android 1.0和1.1中具有与AsyncTask相同功能的类UserTask。它提供了完全一样的API,你需要做的只是把它的代码拷贝的你的程序中。
AsyncTask的目标是替你管理你的线程。前面的代码可以很容易地使用AsyncTask重写。
public void onClick( View v ) { new DownloadImageTask().execute( "http://example.com/image.png" ); } private class DownloadImageTask extends AsyncTask { protected Bitmap doInBackground( String... urls ) { return loadImageFormNetwork( urls[0] ); } protected void onPostExecute( Bitmap result ) { mImageView.setImageBitmap( result ); } }
正如你看到的,使用AsyncTask必须要继承它。使用AsyncTask非常重要的是:AsyncTask的实例必须在UI线程中创建而且只能被使用一次。你可以使用预读AsyncTask的文档来来了解如何使用这个类,下面大概地了解一下它是如何工作的:
你可以使用泛型参数制定任务的参数、中间值(progress values)和任何的最终执行结果
doInBackground()方法会自动地在工作者线程中执行
onPreExecute()、onPostExecute()和onProgressUpdate()方法会在UI线程中被调用
doInBackground()方法的返回值会被传递给onPostExecute()方法
在doInBackground()方法中你可以调用publishProgress()方法,每一次调用都会使UI线程执行一次onProgressUpdate()方法
你可以在任何时候任何线程中取消这个任务
除了官方的文档,你可以阅读Shelves和Photostream源代码中的几个复杂的示例。我强烈地推荐阅读Shelves的源代码,它会使你知道如何在配置更改之间持久化任务以及在activity被销毁时正确的取消任务。
不管是否使用AsyncTask,始终记住以下两个关于单线程模型的准则:不要阻塞UI线程以及一切Android UI操作都在UI线程中执行。AsyncTask仅仅是使你能够更容易地遵守这两条准则。
转自:http://hi.baidu.com/%CE%DE%D0%C4%B1%B1%BE%A9/blog/item/ab6621d2b0adbfc7a8ec9a38.html
发表评论
-
动态更新APK
2011-09-08 12:29 4337开发了一个APK后,往往后续需要进行更新升级。那么,当用户选择 ... -
Android数据保存之PreferenceActivity
2011-09-07 15:49 5743看到很多书中都没有对PreferenceActivit ... -
AsyncTask 的使用
2011-08-22 13:39 6022在开发Android应用时必须遵守单线程模型的原则: ... -
Android Service 之三(Bind Service,使用 AIDL)
2011-08-15 17:57 12130前面写了 Bind Service 的两种实现方式,接下来转一 ... -
Android Service 之三(Bind Service,使用 Messenger)
2011-08-15 17:26 10022上次讲了第一种 Bind Service 的实现方式,今天讲 ... -
Android NOtification 使用
2011-08-12 17:12 4998一、 Notification 简介 在 andro ... -
如何快速启动 Android 模拟器
2011-08-12 11:04 2493一直不知道在创建 AVD 时,那个 "enable ... -
Android 模拟器启动失败(SDL_app:emulator.exe )解决方法
2011-08-12 10:45 3530今天新建了一个AVD,给它划分了512MB的空间,然后启动之, ... -
Android Service 之三(Bind Service, 继承自 Binder 类)
2011-08-10 13:08 29961之前提及过,启动Service有两种方式:startServ ... -
android service 之二(IntentService)
2011-08-09 11:13 31664不管是何种Service,它默认都是在应用程序的主线程(亦即U ... -
android service 之一 (start service)
2011-08-08 15:45 13914我们有两种方式(start与bind)启动一个Service ... -
写Service Demo的时候遇到的一个问题小结一下
2011-08-08 14:29 8517我写了一个 Service 的Demo,但是将启动Servi ... -
百度Android工程师面试题
2011-07-28 09:49 2219百度Android工程师面试题 -
Android中UI主线程与子线程
2011-07-26 14:10 2097在一个Android 程序开始运行的时候,会单独启动一个Pro ... -
Android 之 传感器 应用
2011-07-26 10:42 5267传感器的使用 1.传感器类型: 方向、加速度(重力)、 ... -
Logcat出错:Could not create the view: For input string:
2011-07-22 13:39 2530使用eclipse开发android应用已经一年多了,但今 ... -
Goolge Map API 源码
2011-07-14 14:16 3854由于做GOOGLE MAP 的项目,所以就上网想找它的源码。结 ... -
如何用metersToEquatorPixels实现任意纬度的米到像素的转换
2011-07-14 13:40 4730今天又是神奇的发现:我希望在MapView的Overlay子类 ... -
申请 android google map API key(转)
2011-07-10 14:07 18411.首先要得到你的debug keystore位置: ... -
windows下如何批量下载android源码
2011-05-18 22:56 2595为了在windows下批量下载Android的源码,上网查 ...
相关推荐
Elasticsearch Painless Script入门教程--示例数据。 自Elasticsearch 5.x 引入Painless,使得Elasticsearch拥有了安全、可靠、高性能脚本的解决方案。Painless是Elastic开发并做了专门的优化,相较之前的脚本更...
Painless Vim is written by a professional developer who tried to learn vim a number of times before it finally stuck. I kept falling into the same cycle: I'd read a wide a array of books, online ...
项目中es版本从es2升级到es6之后,使用的groovy废弃,转换为painless脚本,转换过程中经过查询官网总结整理而成的笔记
Painless Git is a distillation of all the best git advice I've found over the years, helping you not only start using git, but start using it well. Once you've got a solid understanding of the basics ...
最好的docker书籍,Painless Docker Basic Edition 英文版。
《A Painless Guide to CRC Error Detection Algorithms》是一份国外的经典资料,由Ross N. Williams所著,详细介绍了循环冗余校验(Cyclic Redundancy Check,简称CRC)算法及其基于表驱动的实现方式。本书于1993年...
Code for a painless q-learning tutorial
项目从es2升级到es6,groovy脚本也要相应的转换为painless脚本,转换过程中遇到了很多坑,特此总结成文档,供大家一起交流学习。
<<React Quickly Painless web apps with React, JSX, Redux, and GraphQL>>原书代码,方便大家学些
这种方法的名称是“共轭梯度法”,而标题中的“painless”则是指本文将会用浅显易懂的方式来介绍这一复杂的数学算法。 首先,共轭梯度法对于求解大规模稀疏线性方程组有着非常重要的意义。由于它在解决这类问题时...
it also makes (de)serialization painless. It wraps around the well-known org.json classes (JSONObject, JSONArray, etc.) which also happen to be included in the Android SDK. As we all know, those ...
BlockingQueue是一种线程安全的数据结构,适合用于生产者消费者模型,它支持等待插入或移除元素的操作,避免了线程间的直接交互。 Java SE 7进一步增强了并发能力,引入了Fork/Join框架,这是一个基于工作窃取算法...
"A Painless Guide to CRC Error Detection Algorithms", Version 3, August 1993. - [2] Jean-loup Gailly, Mark Adler. "ZLIB Compression Document", available at http://zlib.net/. - [3] W. Wesley Peterson,...
无痛的 painless是仅标头的C ++库,它提供了一种在程序中... 在后台,它产生一个线程,监视对该文件的修改。 对该值的更改将立即反映在正在运行的程序中。 例子 # include < painless> # include # include < ios
最后,文章对于如何实现CRC算法提供了详细的指导和建议,包括直接实现、查找表驱动实现、参数化模型实现等多种方式。作者还提到了一些潜在的问题和解决方案,例如软件中的常见错误和大型bug的发现及修正,以及有关...
在"A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS"这篇文章中,作者Ross Williams深入浅出地介绍了CRC的工作原理及其应用。CRC的主要优点在于其高效性和对突发错误的敏感性,即使数据中存在多个连续错误位,...
Android分页库,实现轻松使用Kotlin和Coroutine构建现代建筑 下载 第1步-将JitPack存储库添加到您的构建文件中 allprojects { repositories { .. . maven { url ' https://jitpack.io ' } } } 第2步-添加依赖项...