你的位置:首页 > 操作系统

[操作系统]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> listener;  public void setListener(OnResponseListener<T> listener) {    this.listener = listener;  }  @Override  protected T doInBackground(String... params) {    return null;  }  @Override  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=null;  public void get(){    //创建网络访问实例    Http<User> http=new Http<User>();    //重写接口    http.setListener(new Http.OnResponseListener<User>() {      @Override      public void onResponse(User user) {        user1=user;      }    });    http.execute("xxx.balabala.com");  }}  

 

 

在发送请求的时候很容易就带个参数,请求的方式呢 无非就是get,post   两者的区别呢 大白话的说 get不安全 参数通过url直接传过去  post安全 参数加密一下子

下面贴一下AsyncTask在get和post请求时核心代码    doInBackground方法

GET

 protected T doInBackground(String... params) {    //网络连接对象    HttpURLConnection connection=null;    //输入流 获取网络数据    InputStream is=null;    //字节数组输出流    ByteArrayOutputStream bos=null;    try {      //获取网络连接对象      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);        return t;      }else{        Log.e("error","网络访问失败==========="+code);      }    } catch (IOException e) {      e.printStackTrace();    }finally {      try {        if (bos!=null){          bos.close();        }        if (is!=null){          is.close();        }      } catch (IOException e) {        e.printStackTrace();      }      if (connection!=null){        connection.disconnect();      }    }    return null;  }

POST

post和get的区别  就是post多了一段处理参数的代码

  protected T doInBackground(String... params) {    //分割url 分为地址和参数两部分    String[] strArr=params[0].split("\\?");    HttpURLConnection connection=null;    //输出流    OutputStream os=null;    //输入流    InputStream is=null;    ByteArrayOutputStream bos=null;    try {      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);        return t;      }else{        Log.e("error","网络访问失败==========="+code);      }    } catch (IOException e) {      e.printStackTrace();    }finally {      try {        if (bos!=null){          bos.close();        }        if (is!=null){          is.close();        }      } catch (IOException e) {        e.printStackTrace();      }      if (connection!=null){        connection.disconnect();      }    }    return null;  }