- 浏览: 67976 次
- 性别:
- 来自: 深圳
最新评论
-
andy_叶:
hold_on 写道有 android proguard 语法 ...
android源码中混淆编译 -
hold_on:
有 android proguard 语法文档吗?google ...
android源码中混淆编译
Android UI 单线程模型的编程原则以及AsyncTask 原理
- 博客分类:
- android
导读:oInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecut
在开发Android应用时必须遵守单线程模型的原则:
UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
在单线程模型中始终要记住两条法则:
1. 不要阻塞UI线程
2. 确保只在UI线程中访问Android UI工具包
当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。
比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用
TextView.setText()的.因为其他线程中是不能直接访问主UI线程成员 。
android提供了几种在其他线程中访问UI线程的方法。
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable, long )
Hanlder
这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。
为了解决这个问题,Android 提供了一个工具类:AsyncTask
它使创建需要与用户界面交互的长时间运行的任务变得更简单。
相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
1) 子类化AsyncTask
2) 实现AsyncTask中定义的下面一个或几个方法
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params…), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress…),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。
从网上获取一个网页,在一个TextView中将其源代码显示出来
001 |
package test.list;
|
002 |
|
003 |
import java.io.ByteArrayOutputStream;
|
004 |
|
005 |
import java.io.InputStream;
|
006 |
|
007 |
import java.util.ArrayList;
|
008 |
|
009 |
import org.apache.http.HttpEntity;
|
010 |
|
011 |
import org.apache.http.HttpResponse;
|
012 |
|
013 |
import org.apache.http.client.HttpClient;
|
014 |
|
015 |
import org.apache.http.client.methods.HttpGet;
|
016 |
|
017 |
import org.apache.http.impl.client.DefaultHttpClient;
|
018 |
|
019 |
import android.app.Activity;
|
020 |
|
021 |
import android.app.ProgressDialog;
|
022 |
|
023 |
import android.content.Context;
|
024 |
|
025 |
import android.content.DialogInterface;
|
026 |
|
027 |
import android.os.AsyncTask;
|
028 |
|
029 |
import android.os.Bundle;
|
030 |
|
031 |
import android.os.Handler;
|
032 |
|
033 |
import android.os.Message;
|
034 |
|
035 |
import android.view.View;
|
036 |
|
037 |
import android.widget.Button;
|
038 |
|
039 |
import android.widget.EditText;
|
040 |
|
041 |
import android.widget.TextView;
|
042 |
|
043 |
public class NetworkActivity extends Activity{
|
044 |
|
045 |
private TextView message;
|
046 |
|
047 |
private Button open;
|
048 |
|
049 |
private EditText url;
|
050 |
|
051 |
@Override |
052 |
|
053 |
public void onCreate(Bundle savedInstanceState) {
|
054 |
|
055 |
super .onCreate(savedInstanceState);
|
056 |
|
057 |
setContentView(R.layout.network); |
058 |
|
059 |
message= (TextView) findViewById(R.id.message); |
060 |
|
061 |
url= (EditText) findViewById(R.id.url); |
062 |
|
063 |
open= (Button) findViewById(R.id.open); |
064 |
|
065 |
open.setOnClickListener( new View.OnClickListener() {
|
066 |
|
067 |
public void onClick(View arg0) {
|
068 |
|
069 |
connect(); |
070 |
|
071 |
} |
072 |
|
073 |
}); |
074 |
|
075 |
|
076 |
} |
077 |
|
078 |
private void connect() {
|
079 |
|
080 |
PageTask task = new PageTask( this );
|
081 |
|
082 |
task.execute(url.getText().toString()); |
083 |
|
084 |
} |
085 |
|
086 |
class PageTask extends AsyncTask<String, Integer, String> {
|
087 |
|
088 |
// 可变长的输入参数,与AsyncTask.exucute()对应 |
089 |
|
090 |
ProgressDialog pdialog; |
091 |
|
092 |
public PageTask(Context context){
|
093 |
|
094 |
pdialog = new ProgressDialog(context, 0 );
|
095 |
|
096 |
pdialog.setButton( "cancel" , new DialogInterface.OnClickListener() {
|
097 |
|
098 |
public void onClick(DialogInterface dialog, int i) {
|
099 |
|
100 |
dialog.cancel(); |
101 |
|
102 |
} |
103 |
|
104 |
}); |
105 |
|
106 |
pdialog.setOnCancelListener( new DialogInterface.OnCancelListener() {
|
107 |
|
108 |
public void onCancel(DialogInterface dialog) {
|
109 |
|
110 |
finish(); |
111 |
|
112 |
} |
113 |
|
114 |
}); |
115 |
|
116 |
pdialog.setCancelable( true );
|
117 |
|
118 |
pdialog.setMax( 100 );
|
119 |
|
120 |
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); |
121 |
|
122 |
pdialog.show(); |
123 |
|
124 |
} |
125 |
|
126 |
@Override |
127 |
|
128 |
protected String doInBackground(String... params) {
|
129 |
|
130 |
try {
|
131 |
|
132 |
HttpClient client = new DefaultHttpClient();
|
133 |
|
134 |
// params[0]代表连接的url |
135 |
|
136 |
HttpGet get = new HttpGet(params[ 0 ]);
|
137 |
|
138 |
HttpResponse response = client.execute(get); |
139 |
|
140 |
HttpEntity entity = response.getEntity(); |
141 |
|
142 |
long length = entity.getContentLength();
|
143 |
|
144 |
InputStream is = entity.getContent(); |
145 |
|
146 |
String s = null ;
|
147 |
|
148 |
if (is != null ) {
|
149 |
|
150 |
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
151 |
|
152 |
byte [] buf = new byte [ 128 ];
|
153 |
|
154 |
int ch = - 1 ;
|
155 |
|
156 |
int count = 0 ;
|
157 |
|
158 |
while ((ch = is.read(buf)) != - 1 ) {
|
159 |
|
160 |
baos.write(buf, 0 , ch);
|
161 |
|
162 |
count += ch; |
163 |
|
164 |
if (length > 0 ) {
|
165 |
|
166 |
// 如果知道响应的长度,调用publishProgress()更新进度 |
167 |
|
168 |
publishProgress(( int ) ((count / ( float ) length) * 100 ));
|
169 |
|
170 |
} |
171 |
|
172 |
|
173 |
|
174 |
// 让线程休眠100ms |
175 |
|
176 |
Thread.sleep( 100 );
|
177 |
|
178 |
} |
179 |
|
180 |
s = new String(baos.toByteArray()); }
|
181 |
|
182 |
// 返回结果 |
183 |
|
184 |
return s;
|
185 |
|
186 |
} catch (Exception e) {
|
187 |
|
188 |
e.printStackTrace(); |
189 |
|
190 |
} |
191 |
|
192 |
return null ;
|
193 |
|
194 |
} |
195 |
|
196 |
@Override |
197 |
|
198 |
protected void onCancelled() {
|
199 |
|
200 |
super .onCancelled();
|
201 |
|
202 |
} |
203 |
|
204 |
@Override |
205 |
|
206 |
protected void onPostExecute(String result) {
|
207 |
|
208 |
// 返回HTML页面的内容 |
209 |
|
210 |
message.setText(result); |
211 |
|
212 |
pdialog.dismiss(); |
213 |
|
214 |
} |
215 |
|
216 |
@Override |
217 |
protected void onPreExecute() {
|
218 |
|
219 |
// 任务启动,可以在这里显示一个对话框,这里简单处理 |
220 |
|
221 |
message.setText(R.string.task_started); |
222 |
|
223 |
} |
224 |
|
225 |
@Override |
226 |
|
227 |
protected void onProgressUpdate(Integer... values) {
|
228 |
|
229 |
// 更新进度 |
230 |
|
231 |
System.out.println( "" +values[ 0 ]);
|
232 |
|
233 |
message.setText( "" +values[ 0 ]);
|
234 |
|
235 |
pdialog.setProgress(values[ 0 ]);
|
236 |
|
237 |
} |
238 |
|
239 |
} |
240 |
|
241 |
} |
发表评论
-
解包system.img成HIT archive data格式的包
2014-04-26 11:30 3802昨天解包了一天,HIT archive data格式的sy ... -
打包system.img成HIT archive data格式的包
2014-04-26 11:29 739有些人看了上一篇的解 ... -
system.img解包打包的方法
2013-05-10 18:27 0操作系统:ubuntu10.10可 ... -
apk反编译和重新打包
2013-04-18 18:11 28234相信每位玩机的人对APK ... -
PackageManager
2013-04-02 16:52 1210PackageManager分析(5) ... -
android源码中混淆编译
2013-03-27 15:11 16981.在需要混淆的工程目录下(package/apps/下的 ... -
如何通过反射方法获取com.android.internal.os.PkgUsageStats
2012-11-05 17:45 1923通过com.android.internal.os.P ... -
android 4.0.3最新源码下载编译
2012-09-29 13:57 838首先,开发环境,google建议在ubuntu10.0.4下, ... -
不错的资源网站
2012-09-19 16:38 755最近在爱库网上发现了很多不错的Icon资源站点, Web2.0 ... -
Android下使用Http协议实现多线程断点续传下载
2012-08-30 14:49 37570.使用多线程下载会提升文件下载的速度,那么多线程下载文件的过 ... -
Android 解析后台返回为Json数据实例教程
2012-08-21 16:46 8140大家好,今天给大家分享下Android解析Json的例子,我这 ... -
编写Android app更新模块遇到的问题分析与总结
2012-08-21 14:41 2061前不久接到个任务,在 ...
相关推荐
Android学习笔记(三二):线程:后台异步任务AsyncTask_IT168文库
android UI线程和后台线程交互,包括多线程之AsyncTask等例子展示。。。。。。。。。。。
Android 使用AsyncTask异步更新UI界面
android asynctask的fragment更新UI(附线程管理) 博客地址:http://blog.csdn.net/qq_16064871
Android是单线程模型,耗时的操作必须放在非主线程中执行,对此,我们需要使用多线程/线程池或者AsyncTask等来完成异步加载任务。 博客地址:http://blog.csdn.net/chenzheng8975/article/details/53893666
Android 单线程模型详解及实例 我们今天将会在这篇文章中为大家详细介绍有关Android单线程模型的相关内容。希望初学者们可以通过本文介绍的内容对这一概念有一个充分的认识,并从中对这一系统有一个深刻的认识。 当...
rxjava2 线程间流式处理 asynctask
Android Asynctask 先小试牛刀,了解一下各个方法执行过程,关注博客http://himici.com/
Android学习笔记(三二):线程:后台异步任务AsyncTask
Android AsyncTask的简单Demo,对应Blog文章:http://blog.csdn.net/dolacmeng/article/details/50215519
Android中AsyncTask实现多线程计数,UI主线程运行,启动另一个线程计数并在UI主线程上显示.
Android异步处理二:使用AsyncTask异步更新UI界面。
AsyncTask 异步多线程加载Demo
Android线程,线程池,AsyncTask,HandlerThread和IntentService的用法demo
12_Android 多线程AsyncTask详解
首先明确Android之所以有Handler和AsyncTask 都是为了不阻塞主线程(UI线程) 且UI的更新只能在主线程中完成 因此异步处理是不可避免的 Android为了降低这个开发难度 提供了AsyncTask AsyncTask就是一个封装过的...
在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。 Android 单线程模型概念详解://www.jb51.net/article/112165.htm 在单线程模型中始终要记住两条...
AsyncTask的用法
在Android中使用AsyncTask和Handler线程间交互的方式,详情参见博客:http://www.cnblogs.com/plokmju/p/android_AsyncTask.html和http://www.cnblogs.com/plokmju/p/android_Handler.html
Android AsyncTask异步处理下载网页