android AsynTask处理返回数据和AsynTask使用get,post请求


Android是一个单线程模型,Android界面(UI)的绘制都只能在主线程中进行,若是在主线程中进行耗时的操做,就会影响UI的绘制和事件的响应。因此在android规定,不可在主线中进行耗时操做,不然将发生程序无响应(ANR)问题。
解决办法:开启新的线程进行耗时操做android

开启新的线程能够new Thread()  或实现Runnable接口 程序员

什么要使用AsyncTask呢?json

 若是是使用Thread的run()方法,run()结束以后没有返回值。因此必需要本身创建通讯机制数组

 AsyncTask将全部的线程通讯都封装成回调函数,调用逻辑容易书写。尤为是在异步处理结束以后,有回调函数进行收尾处理。咳咳,程序员都懒的么 安全

Android给咱们提供的一个轻量级的用于处理异步任务的类:AsyncTask   固然是那个简单就用那个咯网络

最后还有一点就是:Android 4.0后禁止在UI线程中执行网络操做~否则会报:android.os.NetworkOnMainThreadException异步

 

什么是AsyncTask(原谅宝宝偷的图   嘿嘿  不过真的解释的很清楚呢)ide

注意:函数

  Task的实例必须在UI Thread中建立post

  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;
    }
相关文章
相关标签/搜索