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;
    }
时间: 2024-08-14 19:29:29

android AsynTask处理返回数据和AsynTask使用get,post请求的相关文章

android onActivityResult()接收返回数据为null的解决方案

对于·app多个界面管理,如果一般使用Activity默认的加载模式,按返回键就会退回上一次操作,就是一种新建一个Activity实例.时间长了就会变得卡顿,一般人会选择手动地在代码中屏蔽返回键,使用app中开发的返回键,这样也可以解决问题. 但是本质问题还是没解决,不可能以后开发也用这样的方法,用多了也烦躁.所以解决这个问题的关键在于了解Activity的加载模式. 第一中加载模式是:standard标准模式,系统默认的加载的模式 android:launchMode="standard&qu

Android开发:向下一个activity传递数据,返回数据给上一个activity

1.向下一个activity传递数据 activity1 1 Button button=(Button) findViewById(R.id.button1); 2 button.setOnClickListener(new OnClickListener() { 3 4 @Override 5 public void onClick(View v) { 6 Intent intent=new Intent("1111111111111111111"); 7 intent.addCa

Android调用系统相机获取返回数据

由于项目需要调用相机,实现上传照片,例如微博,微信中功能.Android中可以非常轻松的调用系统相机,并返回Bitmap数据,但有一点不足,它返回的Bitmap尺寸很小,清晰度不够,这问题将稍后解决.下面通过代码演示. 1.界面布局 res/layout 定义一个简单布局,一个Button和ImageView,分别用于跳转系统相机Activity和显示系统相机返回数据. 1 <LinearLayout xmlns:android="http://schemas.android.com/ap

Android基础之——startActivityForResult启动界面并返回数据,上传头像

在android应用的开发过程中,经常会出现启动一个界面后填写部分内容后带着数据返回启动前的界面,最典型的应用就是登录过程.在很多应用程序的模块中,都有"我的"这个模块,在未登录状态下点击其中的某一项,就会弹出登录界面,登录完成后回到我的界面,会显示一些登录后的数据,这个功能的实现就要用到startActivityForResult. 下面通过一个小demo来说明一下startActivityForResult的使用,以及在实际开发中的一些应用. demo的效果图如下: 主界面布局:

android蓝牙(二)——接收数据

在蓝牙开发中,我们有这样的一个需求:我们的android客户端要始终保持和蓝牙的连接,当蓝牙有数据返回的时候,android客户端就要及时的收取数据,当蓝牙没有数据返回的时候我们就要保持android客户端和蓝牙之间的连接.这个时候我们就要采取socket来实现和蓝牙之间的连接.做项目使用过http轮询去获取数据,但是发现那样总是有一定的弊端.于是就才用了socket方式去获取数据. 实现步骤:1.启动一个service去监听是否有数据返回.一旦有数据返回就启动一个线程去处理数据 2.处理完数据

返回数据给上一个活动

我们都知道,android开发中一个活动跳转时是可以带数据传递给下一个活动的,那么能不能够返回数据给上一个活动呢?答案是肯定的.不过不同的是,返回上一个活动只需要按一下Back键就可以了,并没有一个用于启动活动Intent来传递数据.通过查阅文档你会发现,Activity中还有一个startActivityForResult()方法也是用于启动活动的,但这个方法期望在活动销毁的时候能返回一个结果给上一个活动.毫无疑问,这就是我们所需要的. startActivityForResult()方法接收

android中Activity回传数据

比如从A跳转到B,然后等待从B回传数据: 那么在A中这样跳转: startActivityForResult(intent, 100); 后面那个requestCode要大于0: 然后在A中重写这个方法: @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.e("onActivityResult", "onActivityResult&quo

Android基础知识(6)—数据持久化之数据存储

阅读前,请浏览此处上方目录. Android基础知识(6)-数据持久化之数据存储 本章内容为个人笔记,参考书籍有:<疯狂的android>第3版.<第一行代码> 首先,我们要知道什么是数据持久化. 数据持久化就是指那些内存中的瞬时数据保存到存储设备中,保证即使手机在关机的情况下,这些数据不会丢失.保存在内存中的数据是处于瞬时状态,保存在存储设备中的数据是处于持久状态.持久化技术则是提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换. Android系统主要提供了三种方式用于简

调用contact某个联系人资料后返回数据到原来的Activity

package com.example.sample_5_10; import android.app.Activity; import android.app.Instrumentation.ActivityResult; import android.content.CursorLoader; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import androi