Android网络请求方法 同步异步方法 get、post以及Gson数据解析

时隔多月在10月24日这天整理了一篇个人安卓学习笔记,希望通过这篇博客传递知识,同时也能帮助自己更好的巩固知识。

项目展示
项目整体预览

一、HttpUrlConnection GET和POST请求

HttpURLConnection的Get请求

//创建url,表示要访问的网络
URL url = new URL("http://www.baidu.com");
//构建访问连接对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置访问方式
conn.setRequestMethod("GET");
//设置连接超时
conn.setConnecTimeout(5000);
//获取返回的字节流
InputStream inputStream = conn.getInputStream();
//关闭连接
conn.disconnect();

实现网络请求实现步骤

网络访问必须要在线程中执行才行

  1. 创建URL对象
  2. 构建HTTPURLConnection 连接对象
  3. 设置访问方式
  4. 设置连接超时
  5. 获取返回的字节输入流
  6. 处理字节输入流,转换为字符串,处理界面更新
  7. 关闭连接对象

HttpURLConnection的Post请求

准备链接对象
//设置链接对象的网址
String url = "http://192.161.0.1:8080/Restaurant/user/login";
URL url = new URL(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);    //支持提交数据
conn.setDoInput(true);     //支持接收数据
conn.setRequestMenthod("POST");

json格式数据
conn.setRequestProperty("Conten-Type","application/json");
JSONObject obj = new JSONObject();
obj.put("userName","tom");
obj.put("userPassword","123");
String data = obj.toString();

普通表单数据
conn.setRequestProperty("Content-Type","application/")

二、OkHttp3知识详解

框架流程
OkHttpClient->Request->RealCall->Dispatcher->interceptors->RetryAndFollow/Bridge/Cache/Connect/CallServer

  • OkHttpClient
    • 首先会创建这个OkHttpClient对象,表示我们所有的请求的一个客户端的类,单例创建,只会创建一个
  • Request
    • 创建Request这个对象,这个对象封装了一些请求报文信息,请求URL地址,请求方法(get/post/put/delet…)还有各种请求头,然后通过Builder构建者模式来链式生成Request对象
  • RealCall
    • 通过调用Request.newCall方法来创建一个Call对象,这个Call对象,这个Call对象在我们的OkHttp中的实现类就是RealCall,这个RealCall代表着实际的OkHttp请求,他是连接Request和Response的一个桥梁,通过Call进行同步异步操作
  • Dispatcher
    • 决定OkHttp的同步或者异步,Dispatcher分发器,在他的内部维护了线程池,这个线程池用于执行网络请求,通过之前创建好的RealCall对象,他会添加到Dispathcher里面
    • Dispatcher会不断的从request这个队列中去获取到他所需求的RealCall这个请求,然后判断是否存在缓存,如果没有缓存则通过调用ConnectInterceptor/CallServerInterceptor服务器数据的返回
  • Iinterceptors
    • 不管是同步还是异步,OKhttp内部会通过一个叫interceptors(拦截器列)的东西来进行真正的服务器数据获取,会构建一个拦截器列,然后依次执行整个拦截器中的每个拦截器来将我们服务器获得的数据返回。
    • 无论同步或者异步最终都是会调用拦截器进行分发

基本使用方法

  1. 导入依赖,开启网络访问权限
  2. 创建OkHttpClient对象client
  3. 通过Builder模式创建Request对象、参数必须有url对象;Request.Builder设置更多的参数比如:header、method、get/post等
  4. 使用Client对象,将request对象封装为一个call对象
  5. 通过Call对象的execute()和cancel()等方法完成网络访问
implementation      'com.squareup.okhttp3:okhttp:3.12.1'
debugImplementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'

开启网络访问权限

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

OkHttp进行Get请求

  1. 获取OkHttpClient对象
    OkHttpClient client = new OkHttpClient();
  2. 构造Request对象
    通过建造者模式和链式调用指明进行Get请求,并通过Get请求的地址
Request request = new Request.Builder()
                                 .get()
                                 .url("https://www.baidu.com")
                                 .build();
  1. 将Request封装成为Call
    Call call = client.newCall(request);
  2. 根据需要调用同步或者异步请求方法
//Response response = call.execute();同步请求方法,返回Response会抛出IO异常
   call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        //失败情况
        Toast.makeText(OkHttpRequest.this, "网络访问失败", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        //请求成功
        response = client.newCall(request).execute();
        result = response.body().string();
        runOnUiThread(new Runnable() {//子线程内无法更新,通过runOnUiThread来更新界面Ui
            @Override
            public void run() {
                textView.setText(result);
            }
        });
    }
});

Okhttp通过Post提交键值对

  1. 获取OkHttpClient对象
    OkHttpClient client = new OkHttpClient();
  2. 构建FormBody,传入请求参数
构建构建FormBody formBody = new FormBody.Builder()
                            .add("id","1")
                            .add("name","尹志鹏")
                            .add("password","123456")
                            .build();
  1. 构建Request,将FormBody作为Post方法的参数传入
final Request request = new Request.Builder()
                            .url("http://www.baidu.com/")
                            .post(formBody)
                            .build();
  1. 将Request封装为Call
    Call call = client.newCall(request);
  2. 调用请求重写回调方法
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Toast.makeText(OkHttpActivity.this, "Post Failed", Toast.LENGTH_SHORT).show();
    }


    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String res = response.body().string();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                contentTv.setText(res);
            }
        });
    }
}); 

三、个人项目代码

项目图
项目图

public class OkHttpRequest extends AppCompatActivity implements View.OnClickListener {
    private String TAG = "OkHttpRequest";
    private EditText inputthing;
    private Button tijiaoBtn;
    private Button syncGet;
    private Button asynGet;
    private TextView textView;
    private String result;
    private Request request;
    private Response response;
    private Button OkHttpRequestPostFrom;
    private Button OkHttpRequestPostGson;
    private Gson gson;
    //获取客户端对象
    private static OkHttpClient client = new OkHttpClient();
    private String inputId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ok_http_request);
        init();
    }

    private void init() {
        syncGet = findViewById(R.id.OkHttpRequest_syncGet);
        asynGet = findViewById(R.id.OkHttpRequest_asyncGet);
        textView = findViewById(R.id.OkHttpRequest_tx_text);
        OkHttpRequestPostFrom = (Button) findViewById(R.id.OkHttpRequest_PostFrom);
        OkHttpRequestPostGson = (Button) findViewById(R.id.OkHttpRequest_Gson);
        tijiaoBtn = findViewById(R.id.OkHttpRequest_btn_tijiao);
        inputthing = findViewById(R.id.OkHttpRequest_edText_input);
        tijiaoBtn.setOnClickListener(this);
        OkHttpRequestPostGson.setOnClickListener(this);
        OkHttpRequestPostFrom.setOnClickListener(this);
        syncGet.setOnClickListener(this);
        asynGet.setOnClickListener(this);
        tijiaoBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputId = inputthing.getText().toString();
                Toast.makeText(OkHttpRequest.this, "输入的id值为" + inputId, Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.OkHttpRequest_syncGet://同步Get请求
                initSyncData();
                break;
            case R.id.OkHttpRequest_asyncGet://异步Get请求
                initAsyncData();
                break;
            case R.id.OkHttpRequest_PostFrom://Post请求
                initPostFrom();
                break;
            case R.id.OkHttpRequest_Gson://Gson数据解析
                initGson();
                break;
        }
    }

    /*
     * Gson数据解析方法
     * 1.导入依赖
     * 2.创建实体类
     * 3.实例化对象(gson对象和实体类)
     * 4.获取gson解析数据
     * */
    private void initGson() {
        final Request request = new Request.Builder()
                .get()
                .url("https://www.尹志鹏.com/android-system/user/getUser")
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Toast.makeText(OkHttpRequest.this, "网络请求失败!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                response = client.newCall(request).execute();
                result = response.body().string();
                Gson gson = new Gson();
                final UserList userList = gson.fromJson(result,UserList.class);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(userList.getStudentId());
                    }
                });
            }
        });
    }

    private void initPostFrom() {
        if (inputId == "" || inputId == null) {
            Toast.makeText(this, "未输入参数自动设置为1", Toast.LENGTH_SHORT).show();
            inputId = "1";
        } else {
            String url = "https://www.尹志鹏.com/android-system/user/postParamUser";
            FormBody formBody = new FormBody.Builder()
                    .add("id", inputId)
                    .build();
            request = new Request.Builder()
                    .url(url)
                    .post(formBody)
                    .build();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    client.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Toast.makeText(OkHttpRequest.this, "网络请求失败", Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            result = response.body().string();
                            Log.e(TAG, "onResponse: " + result);
                            OkHttpRequest.this.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    textView.setText(result);
                                }
                            });
                        }
                    });
                }
            }).start();
        }
    }//Post请求

    /*
     * Get请求同步方法
     * 同步调用容易阻塞主线程,一般不适用
     * OKHttpclient client = new OkHttpClient();
     * Request request = new Request.Builder().url(url).build();
     * Request response = client.newCall(request).execute();
     * String message = response.body().string();
     * */
    private void initSyncData() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                /*
                 * 通过Builder设置更多的参数比如header、method、get等
                 * 使用Client对象,将request对象封装成为一个Call对象
                 * 通过Call对象的execute()和cancel()等方法完成网络访问
                 * */
                //构造request对象,通过建造者模式和链式调用指明是Get方式和传入url地址
                request = new Request.Builder()
                        .get()
                        .url("http://尹志鹏.com/web_home/static/api/news/categories.json")//输入需要请求的url
                        .build();
                try {
                    response = client.newCall(request).execute();
                    result = response.body().string();
                    gson = new Gson();
                    final NewsList newsList = gson.fromJson(result, NewsList.class);
                    //不能再子线程更新UI,需要借助runOnUiThread()方法或者handler来处理
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            StringBuffer stringBuilder = new StringBuffer();
                            for (Integer integer : newsList.getExtend()) {
                                stringBuilder.append(" : " + integer);
                            }
                            textView.setText(stringBuilder.toString());
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }//Get同步请求

    /*
     * Get请求异步方法
     * 异步请求调用的回调函数是在子线程,无法在子线程里面更新UI,需要借助runOnUiThread()方法或者Handler来处理
     * OkHttpClient client = new OkHttpClient();
     * Request request = new Request.Builder().url(url).build();
     * client.newCall()request.enqueue.(new CallBack){onFailure(),onResponse()}
     * */
    private void initAsyncData() {
        //新建一个客户端对象
        Request request = new Request.Builder()
                .get()
                .url("https://www.尹志鹏.com/android-system/user/getUser")
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //失败情况
                Toast.makeText(OkHttpRequest.this, "网络访问失败", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //请求成功
//                response = client.newCall(request).execute();
                result = response.body().string();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(result);
                    }
                });
            }
        });
    }//Get异步请求
}

这段时间自己整理的学习笔记,可能不一定完善,如果存在问题还请各位大佬能够批评指正。最后祝各位1024节日快乐!

2020/10/24
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值