syncTask,是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

使用的优点:

l  简单,快捷

l  过程可控

使用的缺点:

l  在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

2 )Handler异步实现的原理和适用的优缺点

AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。

Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。

AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。

AsyncTask定义了三种泛型类型 Params,Progress和Result。

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。

使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:

  • doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
  • onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

有必要的话你还得重写以下这三个方法,但不是必须的:

  • onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
  • onPreExecute()        这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled()             用户调用取消时,要做的操作

使用AsyncTask类,以下是几条必须遵守的准则:

  • Task的实例必须在UI thread中创建;
  • execute方法必须在UI thread中调用;
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
  • 该task只能被执行一次,否则多次调用时将会出现异常;

下面给出一个我写的小demo,仅供大家参考,运行结果如图:

首先是AysncTask类:

  1. package ly.asynctasktest;
  2. import android.content.Context;
  3. import android.os.AsyncTask;
  4. import android.widget.TextView;
  5. import android.widget.Toast;
  6. /**
  7. * Created by kfbmac3 on 16/7/8.
  8. */
  9. /*
  10. AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法。注意继承时需要设定三个泛型Params,
  11. Progress和Result的类型,如AsyncTask<Void,Inetger,Void>:
  12. Params是指调用execute()方法时传入的参数类型和doInBackgound()的参数类型
  13. Progress是指更新进度时传递的参数类型,即publishProgress()和onProgressUpdate()的参数类型
  14. Result是指doInBackground()的返回值类型
  15. doInBackgound() 这个方法是继承AsyncTask必须要实现的,运行于后台,耗时的操作可以在这里做
  16. publishProgress() 更新进度,给onProgressUpdate()传递进度参数
  17. onProgressUpdate() 在publishProgress()调用完被调用,更新进度
  18. */
  19. public class UpdateTextTask extends AsyncTask<Void,Integer,String> {
  20. private Context context;
  21. private String url;
  22. private String postValue;
  23. private TextView text;
  24. UpdateTextTask(Context context , String string , String postValue , TextView text) {
  25. this.context = context;
  26. this.url = string;
  27. this.postValue = postValue;
  28. this.text = text;
  29. }
  30. /**
  31. * 运行在UI线程中,在调用doInBackground()之前执行
  32. * 该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置
  33. */
  34. @Override
  35. protected void onPreExecute() {
  36. Toast.makeText(context,"开始执行",Toast.LENGTH_SHORT).show();
  37. }
  38. /**
  39. * 后台运行的方法,可以运行非UI线程,可以执行耗时的方法
  40. * 这里的Void参数对应AsyncTask中的第一个参数
  41. * 这里的String返回值对应AsyncTask的第三个参数
  42. * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
  43. * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作
  44. */
  45. @Override
  46. protected String doInBackground(Void... params) {
  47. int i=0;
  48. while(i<10){
  49. i++;
  50. //publishProgress 更新进度,给onProgressUpdate()传递进度参数
  51. publishProgress(i);
  52. try {
  53. Thread.sleep(1000);
  54. } catch (InterruptedException e) {
  55. }
  56. }
  57. String result = Common.postGetJson(url,postValue);
  58. //第三个参数为String 所以此处return一个String类型的数据
  59. return result;
  60. }
  61. /**
  62. * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
  63. * 运行在ui线程中,在doInBackground()执行完毕后执行,传入的参数为doInBackground()返回的结果
  64. */
  65. @Override
  66. protected void onPostExecute(String i) {
  67. Toast.makeText(context,i,Toast.LENGTH_SHORT).show();
  68. text.setText(i);
  69. }
  70. /**
  71. * 在publishProgress()被调用以后执行,publishProgress()用于更新进度
  72. * 这里的Intege参数对应AsyncTask中的第二个参数
  73. * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行
  74. * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作
  75. */
  76. @Override
  77. protected void onProgressUpdate(Integer... values)
  78. {
  79. //第二个参数为Int
  80. text.setText(""+values[0]);
  81. }
  82. }

接下来是发送http请求的方法:

  1. package ly.asynctasktest;
  2. import android.util.Log;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.DataOutputStream;
  5. import java.io.InputStream;
  6. import java.net.HttpURLConnection;
  7. import java.net.URL;
  8. import java.util.List;
  9. import java.util.Map;
  10. /**
  11. * Created by kfbmac3 on 16/5/20.
  12. */
  13. public class Common {
  14. public static String postGetJson(String url, String content) {
  15. try {
  16. URL mUrl = new URL(url);
  17. HttpURLConnection mHttpURLConnection = (HttpURLConnection) mUrl.openConnection();
  18. //设置链接超时时间
  19. mHttpURLConnection.setConnectTimeout(15000);
  20. //设置读取超时时间
  21. mHttpURLConnection.setReadTimeout(15000);
  22. //设置请求参数
  23. mHttpURLConnection.setRequestMethod("POST");
  24. //添加Header
  25. mHttpURLConnection.setRequestProperty("Connection", "Keep-Alive");
  26. //接收输入流
  27. mHttpURLConnection.setDoInput(true);
  28. //传递参数时需要开启
  29. mHttpURLConnection.setDoOutput(true);
  30. //Post方式不能缓存,需手动设置为false
  31. mHttpURLConnection.setUseCaches(false);
  32. mHttpURLConnection.connect();
  33. DataOutputStream dos = new DataOutputStream(mHttpURLConnection.getOutputStream());
  34. String postContent = content;
  35. dos.write(postContent.getBytes());
  36. dos.flush();
  37. // 执行完dos.close()后,POST请求结束
  38. dos.close();
  39. // 获取代码返回值
  40. int respondCode = mHttpURLConnection.getResponseCode();
  41. Log.d("respondCode","respondCode="+respondCode );
  42. // 获取返回内容类型
  43. String type = mHttpURLConnection.getContentType();
  44. Log.d("type", "type="+type);
  45. // 获取返回内容的字符编码
  46. String encoding = mHttpURLConnection.getContentEncoding();
  47. Log.d("encoding", "encoding="+encoding);
  48. // 获取返回内容长度,单位字节
  49. int length = mHttpURLConnection.getContentLength();
  50. Log.d("length", "length=" + length);
  51. //            // 获取头信息的Key
  52. //            String key = mHttpURLConnection.getHeaderField(idx);
  53. //            Log.d("key", "key="+key);
  54. // 获取完整的头信息Map
  55. Map<String, List<String>> map = mHttpURLConnection.getHeaderFields();
  56. if (respondCode == 200) {
  57. // 获取响应的输入流对象
  58. InputStream is = mHttpURLConnection.getInputStream();
  59. // 创建字节输出流对象
  60. ByteArrayOutputStream message = new ByteArrayOutputStream();
  61. // 定义读取的长度
  62. int len = 0;
  63. // 定义缓冲区
  64. byte buffer[] = new byte[1024];
  65. // 按照缓冲区的大小,循环读取
  66. while ((len = is.read(buffer)) != -1) {
  67. // 根据读取的长度写入到os对象中
  68. message.write(buffer, 0, len);
  69. }
  70. // 释放资源
  71. is.close();
  72. message.close();
  73. // 返回字符串
  74. String msg = new String(message.toByteArray());
  75. Log.d("Common", msg);
  76. return msg;
  77. }
  78. return "fail";
  79. }catch(Exception e){
  80. return "error";
  81. }
  82. }
  83. }

MainActivity:

  1. package ly.asynctasktest;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.Button;
  6. import android.widget.TextView;
  7. import java.net.URLEncoder;
  8. public class MainActivity extends AppCompatActivity {
  9. private Button btn;
  10. private TextView text;
  11. private String url = "http://192.168.24.104:3000/users";
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.activity_main);
  16. btn = (Button) findViewById(R.id.btn);
  17. text = (TextView) findViewById(R.id.text);
  18. btn.setOnClickListener(new View.OnClickListener() {
  19. @Override
  20. public void onClick(View v) {
  21. Update();
  22. }
  23. });
  24. }
  25. private void Update(){
  26. try{
  27. String value = URLEncoder.encode("username", "UTF-8") + "=" +
  28. URLEncoder.encode("anwei", "UTF-8") + "&" +
  29. URLEncoder.encode("userfullname", "UTF-8") + "=" +
  30. URLEncoder.encode("安威", "UTF-8");
  31. UpdateTextTask updatetext = new UpdateTextTask(this, url, value , text);
  32. updatetext.execute();
  33. }catch(Exception e){
  34. text.setText("error");
  35. }
  36. }
  37. }

需要注意的问题依然是要在AndroidManifest.xml文件中添加网络权限:

    1. <uses-permission android:name="android.permission.INTERNET"/>

Android Studio利用异步任务AsyncTask发送post请求获取json数据的更多相关文章

  1. android通过httpClient请求获取JSON数据并且解析

    使用.net创建一个ashx文件,并response.write  json格式 public void ProcessRequest(HttpContext context) { context.R ...

  2. 发送Ajax请求获取JSON格式数据

    Aspx前端页面: <script type="text/javascript"> $(function () { $.getJSON("Ajax/TestA ...

  3. 异步请求获取JSON数据

    json格式的数据广泛应用于异步请求中前后端的数据交互,本文主要介绍几种使用场景和使用方法. <script type="text/javascript"> funct ...

  4. 使用Retrofit发送POST请求提交JSON数据

    Retrofit官网:https://square.github.io/retrofit/ 示例如下 HttpService.java import okhttp3.RequestBody; impo ...

  5. Android Volley 库通过网络获取 JSON 数据

    本文内容 什么是 Volley 库 Volley 能做什么 Volley 架构 环境 演示 Volley 库通过网络获取 JSON 数据 参考资料 Android 关于网络操作一般都会介绍 HttpC ...

  6. 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回

    作者:ssslinppp      时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...

  7. android客户端从服务器端获取json数据并解析的实现代码

    今天总结一下android客户端从服务器端获取json数据的实现代码,需要的朋友可以参考下   首先客户端从服务器端获取json数据 1.利用HttpUrlConnection /** * 从指定的U ...

  8. (转)android客户端从服务器端获取json数据并解析的实现代码

    今天总结一下android客户端从服务器端获取json数据的实现代码,需要的朋友可以参考下       首先客户端从服务器端获取json数据 1.利用HttpUrlConnection   复制代码 ...

  9. android客户端从服务器端获取json数据并解析的实现代码(重要)

    首先客户端从服务器端获取json数据 1.利用HttpUrlConnection /** * 从指定的URL中获取数组 * @param urlPath * @return * @throws Exc ...

随机推荐

  1. HTML 速成

    html零基础者入. 记得学计算机网络的时候好像有学过一些HTML,但没运用起来都忘光了.近来想学学如何写网页.就从html(HyperText Markup Language超文本标记语言)入手了. ...

  2. WCF、Web API、WCF REST、Web Service 区别

    Web Service It is based on SOAP and return data in XML form. It support only HTTP protocol. It is no ...

  3. iOS基础 - 手势识别 与 手势说明

    一.使用手势识别的四个步骤 1> 实例化手势识别 - (id)initWithTarget:(id)target action:(SEL)action; 2> 设置手势识别属性 3> ...

  4. jQuery手机对话框插件

    最近,公司一直在做微网站之类的,一直在看别的微网站,发现一些对话框的样式很不错,所以自己就动手把样式剥离出来写成一个简单的插件,方便其他项目中使用到.废话不多说,上插件源码: /* *jQuery简单 ...

  5. Controller 和 Action (2)

    Controller 和 Action (2) 继上一篇文章之后,本文将介绍 Controller 和 Action 的一些较高级特性,包括 Controller Factory.Action Inv ...

  6. ecexl操作

    /// <summary> /// 写入ecexl /// </summary> /// <param name="dt"></param ...

  7. MS数据库优化查询最常见的几种方法

    1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 5.网络速度慢 6.查询出的数据量过大 ...

  8. iOS 动画类型 笔记

    #pragma mark Core Animation - (IBAction)buttonPressed1:(id)sender { UIButton *button = (UIButton *)s ...

  9. 基于Hadoop开发网络云盘系统客户端界面设计初稿

    基于Hadoop开发网络云盘系统客户端界面设计初稿 前言: 本文是<基于Hadoop开发网络云盘系统架构设计方案>的第二篇,针对界面原型原本考虑有两个方案:1.类windows模式,文件夹 ...

  10. ORA-12520错误解决方法

    ORA-12520监听程序无法为请求的服务器类型找到可用的处理程序 以下不知道是不是解决方法的方法,因为我只重启下oracle服务就好了,并没进行任何修改 引用别人的文章: 1)数据库是专用服务器,但 ...