如何获取AsyncTask 支付宝异步通知返回值处理的返回值

Android AsyncTask实现异步处理任务的方法详解
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Android AsyncTask实现异步处理任务的方法详解的相关资料,需要的朋友可以参考下
Android AsyncTask实现异步处理任务的方法详解
在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
Android 单线程模型概念详解:
在单线程模型中始终要记住两条法则:
不要阻塞UI线程
确保只在UI线程中访问Android UI工具包
当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。
比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的.因为其他线程中是不能直接访问主UI线程成员
Android提供了几种在其他线程中访问UI线程的方法。
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable, long )
&这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。
为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
◆Params 启动任务执行的输入参数,比如HTTP请求的URL。
◆Progress 后台任务执行的百分比。
◆Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
子类化AsyncTask
实现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只能被执行一次,否则多次调用时将会出现异常
从网上获取一个网页,在一个TextView中将其源代码显示出来
package test.
import java.io.ByteArrayOutputS
import java.io.InputS
import java.util.ArrayL
import org.apache.http.HttpE
import org.apache.http.HttpR
import org.apache.http.client.HttpC
import org.apache.http.client.methods.HttpG
import org.apache.http.impl.client.DefaultHttpC
import android.app.A
import android.app.ProgressD
import android.content.C
import android.content.DialogI
import android.os.AsyncT
import android.os.B
import android.os.H
import android.os.M
import android.view.V
import android.widget.B
import android.widget.EditT
import android.widget.TextV
public class NetworkActivity extends Activity{
private TextV
private EditT
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.network);
message= (TextView) findViewById(R.id.message);
url= (EditText) findViewById(R.id.url);
open= (Button) findViewById(R.id.open);
open.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
connect();
private void connect() {
PageTask task = new PageTask(this);
task.execute(url.getText().toString());
class PageTask extends AsyncTask&String, Integer, String& {
// 可变长的输入参数,与AsyncTask.exucute()对应
public PageTask(Context context){
pdialog = new ProgressDialog(context, 0);
pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
pdialog.setCancelable(true);
pdialog.setMax(100);
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pdialog.show();
protected String doInBackground(String... params) {
HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
String s =
if(is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while((ch = is.read(buf)) != -1) {
baos.write(buf, 0, ch);
if(length & 0) {
// 如果知道响应的长度,调用publishProgress()更新进度
publishProgress((int) ((count / (float) length) * 100));
// 让线程休眠100ms
Thread.sleep(100);
s = new String(baos.toByteArray());
// 返回结果
} catch(Exception e) {
e.printStackTrace();
protected void onCancelled() {
super.onCancelled();
protected void onPostExecute(String result) {
// 返回HTML页面的内容
message.setText(result);
pdialog.dismiss();
protected void onPreExecute() {
// 任务启动,可以在这里显示一个对话框,这里简单处理
message.setText(R.string.task_started);
protected void onProgressUpdate(Integer... values) {
// 更新进度
System.out.println(""+values[0]);
message.setText(""+values[0]);
pdialog.setProgress(values[0]);
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具另外一篇比较详细的博文:
/questions/9671546/asynctask-android-example
AsyncTask的基本用法
首先来看一下AsyncTask的基本用法,由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它。在继承时我们可以为AsyncTask类指定三个泛型参数,这三个参数的用途如下:
在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。
2. Progress
后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
因此,一个最简单的自定义AsyncTask就可以写成如下方式:
1 class DownloadTask extends AsyncTask&Void, Integer, Boolean& {
这里我们把AsyncTask的第一个泛型参数指定为Void,表示在执行AsyncTask的时候不需要传入参数给后台任务。第二个泛型参数指定为Integer,表示使用整型数据来作为进度显示单位。第三个泛型参数指定为Boolean,则表示使用布尔型数据来反馈执行结果。
当然,目前我们自定义的DownloadTask还是一个空任务,并不能进行任何实际的操作,我们还需要去重写AsyncTask中的几个方法才能完成对任务的定制。经常需要去重写的方法有以下四个:
1. onPreExecute()
这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。
2. doInBackground(Params...)
这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。
3. onProgressUpdate(Progress...)
当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
4. onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说提醒任务执行的结果,以及关闭掉进度条对话框等。
因此,一个比较完整的自定义AsyncTask就可以写成如下方式:
1 class DownloadTask extends AsyncTask&Void, Integer, Boolean& {
protected void onPreExecute() {
progressDialog.show();
protected Boolean doInBackground(Void... params) {
while (true) {
int downloadPercent = doDownload();
publishProgress(downloadPercent);
if (downloadPercent &= 100) {
} catch (Exception e) {
return false;
return true;
protected void onProgressUpdate(Integer... values) {
progressDialog.setMessage("当前下载进度:" + values[0] + "%");
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result) {
Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();
Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();
这里我们模拟了一个下载任务,在doInBackground()方法中去执行具体的下载逻辑,在onProgressUpdate()方法中显示当前的下载进度,在onPostExecute()方法中来提示任务的执行结果。如果想要启动这个任务,只需要简单地调用以下代码即可:
1 new DownloadTask().execute();
以上就是AsyncTask的基本用法,怎么样,是不是感觉在子线程和UI线程之间进行切换变得灵活了很多?我们并不需求去考虑什么异步消息处理机制,也不需要专门使用一个Handler来发送和接收消息,只需要调用一下publishProgress()方法就可以轻松地从子线程切换到UI线程了。
以上只是实现了AsyncTask的用法,具体的实现机制,需要参考大神郭霖的博客了。http://blog.csdn.net/guolin_blog/article/details/
阅读(...) 评论()android AsynTask处理返回数据和AsynTask使用get,post请求
Android是一个单线程模型,Android界面(UI)的绘制都只能在主线程中进行,如果在主线程中进行耗时的操作,就会影响UI的绘制和事件的响应。所以在android规定,不可在主线中进行耗时操作,否则将发生程序无响应(ANR)问题。
解决办法:开启新的线程进行耗时操作
开启新的线程可以new Thread()&或实现Runnable接口
什么要使用AsyncTask呢?
如果是使用Thread的run()方法,run()结束之后没有返回值。所以必须要自己建立通信机制
AsyncTask将所有的线程通信都封装成回调函数,调用逻辑容易书写。尤其是在异步处理结束之后,有回调函数进行收尾处理。咳咳,程序员都懒的么
Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask&& 当然是那个简单就用那个咯
最后还有一点就是:Android 4.0后禁止在UI线程中执行网络操作~不然会报:android.os.NetworkOnMainThreadException
什么是AsyncTask(原谅宝宝偷的图&& 嘿嘿& 不过真的解释的很清楚呢)
 Task的实例必须在UI Thread中创建
 execute方法不惜在UI thread中创建
 task只能被执行一次 多次调用时会出现异常
通用AsyncTask 以及在主线程中使用网络请求回返的数据
&&&通用AsyncTask是什么意思呢&发送不同的请求返回不同类型的数据 难道要一个类型写个AsyncTask 岂不是麻烦死咯
&& 还有一种情况& 我们通过异步任务得到了一个对象然后在一下行立刻使用这个对象逻辑完全没问题但是运行之后会报空指针异常。这是怎么回事呢?&&&&&&&
&& AsycnTask开始了一个新的线程,但是主线程并没有停止还在继续运行,马上就使用这个对象,而你新开的线程可能正在访问网络这个对象为空
&& 你无法确定AsycnTask什么时候才能获取到数据,网快嗖的一下就好了,网慢就要等好久。
看一个简略的小例子
首先呢& 我们使用异步任务的时候要处理不同类型的数据把这个Http设置泛型类第三个参数返回值类型设置为泛型不管你是什么类型的数据全部ok
我又写了一个接口作为Http的属性& 在onPostExecute方法调用其中的onResponse方法在Test中实现接口
这个接口的作用完全可以理解为一个监听事件 checkbox的改变监听触发条件是 是否选中这个接口监听是否有数据& 完成网络访问有数据的时候就调用
我们在主线程中完成接口的实现已经在主线程中实现了返回来的数据还不是任君宰割阿~~~~~
public class Http&T& extends AsyncTask&String,Void,T& {
private OnResponseListener&T&
public void setListener(OnResponseListener&T& listener) {
this.listener =
protected T doInBackground(String... params) {
protected void onPostExecute(T t) {
super.onPostExecute(t);
if (listener!=null){
listener.onResponse(t);
//接口 类似一个监听事件
public interface OnResponseListener&T&{
void onResponse(T t);
//获取数据的测试类
public class Test {
//要获取的user对象
private User user1=
public void get(){
//创建网络访问实例
Http&User& http=new Http&User&();
//重写接口
http.setListener(new Http.OnResponseListener&User&() {
public void onResponse(User user) {
http.execute("");
在发送请求的时候很容易就带个参数,请求的方式呢 无非就是get,post&两者的区别呢大白话的说get不安全参数通过url直接传过去post安全参数加密一下子
下面贴一下AsyncTask在get和post请求时核心代码doInBackground方法
protected T doInBackground(String... params) {
//网络连接对象
HttpURLConnection connection=
//输入流 获取网络数据
InputStream is=
//字节数组输出流
ByteArrayOutputStream bos=
//获取网络连接对象
connection=(HttpURLConnection) new URL(params[0]).openConnection();
//设置get请求 必须大写
connection.setRequestMethod("GET");
//获取网络请求码 200 400 500之类 不懂百度
int code=connection.getResponseCode();
if(code==200){
is=connection.getInputStream();
//临时字节数组
byte [] b=new byte[1024];
int len=-1;
bos=new ByteArrayOutputStream();
while ((len=is.read(b))!=-1){
//写入数据
bos.write(b,0,len);
String json=bos.toString("utf-8");
T t=JSON.parseObject(json,type);
Log.e("error","网络访问失败==========="+code);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bos!=null){
bos.close();
if (is!=null){
is.close();
} catch (IOException e) {
e.printStackTrace();
if (connection!=null){
connection.disconnect();
post和get的区别& 就是post多了一段处理参数的代码
protected T doInBackground(String... params) {
//分割url 分为地址和参数两部分
String[] strArr=params[0].split("\\?");
HttpURLConnection connection=
OutputStream os=
InputStream is=
ByteArrayOutputStream bos=
connection=(HttpURLConnection) new URL(strArr[0]).openConnection();
connection.setRequestMethod("POST");
//设置允许输入 输出 默认值true 不写也可以
connection.setDoOutput(true);
connection.setDoInput(true);
os=connection.getOutputStream();
//把参数写入
os.write(strArr[1].getBytes("utf-8"));
os.close();
int code=connection.getResponseCode();
if(code==200){
is=connection.getInputStream();
byte [] b=new byte[1024];
int len=-1;
bos=new ByteArrayOutputStream();
while ((len=is.read(b))!=-1){
bos.write(b,0,len);
String json=bos.toString("utf-8");
T t=JSON.parseObject(json,type);
Log.e("error","网络访问失败==========="+code);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bos!=null){
bos.close();
if (is!=null){
is.close();
} catch (IOException e) {
e.printStackTrace();
if (connection!=null){
connection.disconnect();
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持网管之家!
顶一下(0) 踩一下(0)
热门标签:随笔 - 23&
评论 - 98&
&&&&&&&&&&&
  在上一篇文章中《》,我们知道Android的UI主线程主要负责处理用户的按键事件、用户的触屏事件以及屏幕绘图事件等;既然UI老人家都这么忙了,我们这些开发者肯定不能不识趣的去添乱阻塞UI线程什么的,否则UI界面万一停止响应了呢&&这不是招骂的节奏么?!所以我们知道用Handler+Thread的方法,在子线程中处理耗时的任务,任务完成后通过Handler通知UI主线程更新UI界面,皆大欢喜有木有。
  可是这样,还是有某些人觉得用Handler+Thread的代码会比较繁琐,当然这个某些人里面包括我们伟大的谷歌。所以AsyncTask(异步任务)在Android 1.5中横空出世;相对于Handler来说,由于比较好的封装,AsyncTask显得更加轻量级一点,适用于简单的异步处理;当然使用起来也比较简洁,果然是谷歌的亲儿子!
  AsyncTask是一个抽象类,通常是被继承的命。AsyncTask的内部会维持一个静态的线程池,每个后台任务自然也会被提交到线程池中运行,同时也使用Handler+Thread的机制来调用AsyncTask的各个回调方法;回调方法是在主线程运行的,所以该干什么我们都懂(~ o ~)~zZ(赶紧跟UI界面套近乎呀)。
我们知道AsyncTask&Params, Progress, Result&是抽象类,我们可以在这里面看出它支持三种泛型:
1、Params:我们的AsyncTask要开始干活时,我们给他的输入的参数的类型,也就是传递给后台的参数
2、Progress:AsyncTask向我们报告它干活进度的参数类型,举个例子就是下载进度的百分比
3、Result:后台执行任务完成,返回的结果的参数类型
如果某个泛型我们不需要指定,我们可以大大方方的指定Void,没事AsyncTask不会伤心滴。
当然谷歌也帮我们将AsyncTask的后台任务运行的五种状态,分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务。每种状态在AsyncTask中各有相应的回调方法。
1、准备运行:onPreExecute(),在任务开启时该回调方法立即在UI线程中被调用,同时也是在执行后台耗时操作前被调用;通常该方法用于完成一些初始化工作,比如在界面上显示进度条等。
2、正在后台运行:doInBackground(Params...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用,重写该方法就是后台线程将要完成的耗时任务;由于是由后台线程调用,所以我们不能直接在这里更新UI界面,应该使用publishProgress(Progress...)触发回调方法onProgressUpdate(Progress...)进行进度更新;任务计算的结果必须由该函数返回,并被传递到onPostExecute()中。
3、进度更新:onProgressUpdate(Progress...),在doInBackground()中调用publishProgress()方法更新任务的执行进度,将会在主线程中触发该方法,一般用于动态地显示一个进度条。
4、完成后台任务:onPostExecute(Result),当doInBackground()完成后,系统会自动调用onPostExecute()方法,并将doInBackground()的返回值传递给该方法。
5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用。
参考代码:
public class MainActivity extends ActionBarActivity implements OnClickListener{
private ProgressB
private TextV
private DownT
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startdownload = (Button) findViewById(R.id.startdownload);
probar = (ProgressBar) findViewById(R.id.probar);
tv = (TextView) findViewById(R.id.tv);
startdownload.setOnClickListener(this);
public void onClick(View v) {
task = new DownTask();//同一个AsyncTask的execute只能调用一次
task.execute("输入参数,可为空");//调用execute后将会回调onPreExecute方法
class DownTask extends AsyncTask&String, Integer, String&{
@Override//该方法非在主线程运行,可进行耗时操作,不可更新UI界面,其他方法为主线程运行
protected String doInBackground(String... params) {//params为execute输入的参数
for(int i = 1; i &= 100; i++){
try {//模拟下载操作
Thread.sleep(333);
publishProgress(i);//传递参数i并触发onProgressUpdate回调方法
} catch (InterruptedException e) {
e.printStackTrace();
String result = "任务已完成";
return//将调用onPostExecute,并将result传给该回调方法
protected void onPreExecute() {//该回调方法执行完毕后,将会调用doInBackground
probar.setMax(100);
probar.setProgress(0);
tv.setText("开始下载");
protected void onPostExecute(String result) {//doInBackground结束后回调该方法,结束。
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
tv.setText("下载完成");
protected void onProgressUpdate(Integer... values) {//通知UI界面更新
probar.setProgress(values[0]);
布局文件:
&LinearLayout xmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" &
android:id="@+id/startdownload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载"/&
&ProgressBar
android:id="@+id/probar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal"
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
&/LinearLayout&
代码讲解:
1、点击Button后先实例化一个AsyncTask的继承子类,此时将会创建一个task。接下来变执行execute(params)方法启动异步任务。(同一个AsyncTask的实例只能执行execute一次,多次执行会抛出错误)。
2、在execute()被执行后,将会触发onPreExecute()回调方法,设置进度条的初始属性。在onPreExecute()执行完毕后,将会在后台线程开始执行doInBackground(params),该方法接收execute传入的参数,进行耗时操作,这里是模拟网络文件下载任务。
3、doInBackground()在后台线程运行中,如果需要与UI主线程交互更新进度,可以调用publishProgress(values)方法,将会触发位于UI主线程运行的onProgressUpdate(values)的回调方法,代码中在这里更新进度条的进度。
4、&当后台任务执行完成后,调用onPostExecute(Result),传入的参数是doInBackground()中返回的对象。
1、不要在同一个AsyncTask实例中多次执行execute(),正确的方法是new一个AsyncTask执行一次execute()。
2、耗时任务一定要在doInBackground()中处理,不要在其他回调方法中处理耗时任务以免引起UI主线程的阻塞。
3、不要再doInBackground()中更新UI界面,应该通过publishProgress()调用回调方法更新UI。
4、onCancelled()只能触发AsyncTask的cancel()方法,并无法取消正在线程池运行的线程任务,但可以通过标志位来停止线程任务。
5、在不同的android版本中,AsyncTask多任务运行,有些是可以并行有些则是顺序执行,不过在高版本Android中,可以通过指定参数设置线程池执行规则。
6、AsyncTask适合处理短时间的操作,长时间的操作,比如下载一个很大的视频,这就需要你使用自己的线程来下载,不管是断点下载还是其它的。
作者:enjoy风铃出处:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了。
阅读(...) 评论()

我要回帖

更多关于 js获取异步返回值 的文章

 

随机推荐