Android网络请求归纳 HttpUrlConnection| Vollety|OKHttp3|Retrofit2

1.网络基础知识:

     Android网络API库有哪些?
     HttpUrlConnection: jdk内置
     HttpClient:android提供,6.0被删除
     Volley: google 2013年提供库
     
     HTTP请求方式:GET|POST请求|DELETE...
     GET请求格式: 
     请求行:   POST /books/java.html HTTP/1.1    请求方式  路径 版本
     请求头:   key/value格式
     Accept: */*
     Host: localhost   服务器IP
     User-Accept: Mozilla/4.0  请求客户端类型
     Connection: kekp-Alive   保持连接,一个连接可以发多个请求 
     Referer: http://localhost/links.jsp   
     
     请求体:  GET请求没有
     name=tom&pwd=123
     
     GET请求参数携带在请求头中:GET /books/java.html?id=1 HTTP/1.1
     *********************************************
     HTTP响应:
     响应行:  HTTP/1.1  200 0K   响应状态吗200
     响应头:
      Content-Type: text/html    
      Date: 
      Cache-control:private
     响应体

2. 网络API  HttpUrlConnection 使用

2.1.  HttpUrlConnection 发送GET请求 获取文本

 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
  public void getMethod(View view) {

        new Thread(){
            //3. 在分线程, 发送请求, 得到响应数据
            public void run() {
                try {
                    String path = "http://192.168.2.110:8080/Web001/HomeServlet?id=1";
                 // 设置地址
                    URL url = new URL(path);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                //设置请求方式
                    connection.setRequestMethod("GET");
                    // 设置客户端请求超时时间
                    connection.setConnectTimeout(5000);
                    // 设置读取服务器数据返回数据的时间
                    connection.setReadTimeout(6000);
                    // 连接是服务器
                    connection.connect();
                   // 获取请求状态码
                    int responseCode = connection.getResponseCode();
                    if(responseCode==200) {
                        //得到InputStream, 并读取成String
                        InputStream is = connection.getInputStream();
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        byte[] buffer = new byte[1024];
                        int len = -1;
                        while((len=is.read(buffer))!=-1) {
                            baos.write(buffer, 0, len);
                        }
                        final String result = baos.toString();

                        baos.close();
                        is.close();

                        //4. 在主线程更新UI
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.e("denganzhi1",result);
                            }
                        });
                    }
                    //7). 断开连接
                    connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e("denganzhi1","请求出异常了");
                }
            }
        }.start();

    }

2.1.  HttpUrlConnection 发送POST请求 获取文本,下载文件,图片

  public void getMethodPost(View view) {
        //1. 显示ProgressDialog
        final ProgressDialog dialog = ProgressDialog.show(this, null, "正在加载中...");
        //2. 启动分线程
        new Thread(new Runnable() {
            //3. 在分线程, 发送请求, 得到响应数据
            @Override
            public void run() {
                try {
                    // 设置地址 URL
                    URL url = new URL("http://192.168.2.110:8080/Web001/HomeServlet");
                   // 获取HttpURLConnection
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                 // 设置请求头
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(5000);
                    connection.setReadTimeout(5000);
                    // 连接服务器
                    connection.connect();
                    // 发请求, 得到响应数据
                    // 设置请求体
                    OutputStream os = connection.getOutputStream();
                    String data = "name=Tom2&age=12";
                    os.write(data.getBytes("utf-8"));
                    //得到响应码, 必须是200才读取
                    int responseCode = connection.getResponseCode();
                    if(responseCode==200) {
                        //得到InputStream, 并读取成String
                        // TCP 服务器不断的往客户端写入数据
                        InputStream is = connection.getInputStream();
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        byte[] buffer = new byte[1024];
                        int len = -1;
                        //FileOutputStream fos = new FileOutputStream(apkFile);
                        while((len=is.read(buffer))!=-1) {
                            // fos.write(buffer, 0, len);
                            // 如果是文件图片,直接写入FileOutPutStream
                            // 文本写入  内存中直接显示
                            baos.write(buffer, 0, len);
                        }
                        final String result = baos.toString();
                        // fos.close();
                        baos.close();
                        is.close();

                        //4. 在主线程, 显示得到的结果, 移除dialog
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.e("denganzhi1",result);
                                dialog.dismiss();
                            }
                        });
                    }
                    os.close();
                    //7). 断开连接
                    connection.disconnect();
                } catch (Exception e) {
                    Log.e("denganzhi1","请求出异常了");
                    e.printStackTrace();
                    dialog.dismiss();
                }
            }
        }).start();
    }

3. Vollety使用

3.1. Volley发送 GET 请求, Volley是队列,把请求加入队列即可,对大文件操作不是很好

  private RequestQueue queue;
	   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        queue = Volley.newRequestQueue(this);
    }
	 public void getVolleyGet(View view) {
        String path = "http://192.168.2.110:8080/Web001/HomeServlet?id=1";

        StringRequest request = new StringRequest(path, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {//在主线程执行
                Log.e("denganzhi1",response);
            }
        }, null);
        //将请求添加到队列中
        queue.add(request);
    }

3.2. Volley发送POST  请求

 public void getVolleyPost(View view) {
        String path = "http://192.168.2.110:8080/Web001/HomeServlet";
        StringRequest request = new StringRequest(Request.Method.POST, path, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.e("denganzhi1",response);
            }
        }, null){
            //重写此方法返回参数的map作为请求体
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> map = new HashMap<String, String>();
                map.put("name", "Tom6");
                map.put("age", "16");
                return map;
            }
        };
        //将请求添加到队列中
        queue.add(request);
    }

4. OKHttp3使用

需要依赖库:okio-1.9.0.jar | okhttp-3.4.1.jar

4.1. okhttp3发送GET 请求

    /***
     * okhttp3使用GET请求,看官网,官网有案例  https://square.github.io/okhttp/
     */
    private OkHttpClient client = new OkHttpClient();
    private String get(String url) throws IOException {
        okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .build();
        okhttp3.Response response = client.newCall(request).execute();
        return response.body().string();
    }

    String result=null;
    public void okhttpGET(View view) throws IOException {
     new Thread(){
         @Override
         public void run() {
             super.run();
             try {
                 // 必须在子线程中执行,所以okttp需要封装
                  result= get("http://192.168.2.110:8080/Web001/HomeServlet?id=1");
             } catch (IOException e) {
                 e.printStackTrace();
             }

             runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                    Log.e("denganzhi1",result);
                 }
             });
         }
     }.start();

    }

4.2. okhttp3发送POST 请求

/**
     * okhttp 请求POST 案例
     * 可以请求文本,也可以下载文件、图片
     * 上传图片、文件
     */
    public static final MediaType JSON
            = MediaType.parse("application/json; charset=utf-8");
    private String post(String url, String json) throws IOException {
        // 这里是请求体
        RequestBody body = RequestBody.create(JSON, json);
        okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .post(body)
                .build();
        okhttp3.Response response = client.newCall(request).execute();
        return response.body().string();
    }
    String result2=null;
    public void okhttpPOST(View view) {

        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    result2=  post("http://192.168.2.110:8080/Web001/HomeServlet","");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.e("denganzhi1",result2);
                    }
                });
            }
        }.start();
    }

5.  Retrofit2使用

5.1.Retrofit2就是对okhttp的封装
 基础使用:

5.1.1 添加依赖

 compile 'io.reactivex.rxjava2:rxjava:2.0.8'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'    // 添加Retrofit2的依赖
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'   // RxJava必须要指定返回数据类型解析器,指定gson,那么直接返回List或者Bean,Gson解析器
    compile 'com.squareup.retrofit2:converter-scalars:2.1.0'     // 如果RxJava服务器返回的是字符串,那么使用这个字符串解析器,字符串解析器
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'         // retrofit2和 rxjava 结合库

5.1.2. 代码实现

    1. Retrofit 参数携带方式
@Field : post请求参数
@Path:  GET 请求拼接URL
   第一种GET请求参数拼接: REST风格
   @GET("group/{id}/users")
   Call<List<User>> groudList(@Path("id") int groupId)
   
   2.第二中参数拼接方式:
   loginGet(@Query("username") String uname,
                                 @Query("password") String password);
   URL: MyServlet?username=xiaoming&password=123

2.1. 声明接口: LoginService

/**
	 * 发送GET请求
	 *  @Qeury  缺点,原来是一个一个参数的传递,可以传递 Map
	 */
	@GET("MyServlet")
	public Call<String> loginGet(@Query("username") String uname,
								 @Query("password") String password);

2.2.  调用接口
2.3. 使用Map代替 上面零散参数传递  使用 ScalarsConverterFactory

  public void sendRequest(View view) throws IOException {
        /***
         * Gson: com.squareup.retrofit2:converter-gson
         Jackson: com.squareup.retrofit2:converter-jackson
         Moshi: com.squareup.retrofit2:converter-moshi
         Protobuf: com.squareup.retrofit2:converter-protobuf
         Wire: com.squareup.retrofit2:converter-wire
         Simple XML: com.squareup.retrofit2:converter-simplexml
         Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
         接收数据格式转化器
         */
        //http://192.168.168.157:8080/Web001/MyServlet
        Retrofit retrofit2 = new Retrofit.Builder().baseUrl("http://192.168.168.157:8080/Web001/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();

        LoginService loginService= retrofit2.create(LoginService.class);
        Map<String, String> pramsMap = new HashMap<>();
        pramsMap.put("username","xiaoming");
        pramsMap.put("password","123");
        // 参数统一封装,Map
        Call<String> callLogin=loginService.loginMap(pramsMap);
       //  loginService.login("xaiohei","456");    // GET请求传递参数

        // 同步方法  Caused by: android.os.NetworkOnMainThreadException 异常
      //  Response<String> call = callLogin.execute();
        // Retrofit核心的实现动态代理,内部源码
        // 异步处理逻辑
         callLogin.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                String result =response.body();
                Log.e(TAG,"成功:"+result);
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Log.e(TAG,"失败");
            }
        });
    }

3. 服务器直接返回List 、实体Bean 使用 GsonConverterFactory 转化器

3.1. 声明接口: LoginService 声明方法

/**
	 * 发送post请求
	 * 
	 * @param username
	 * @param password
	 * @return
	 * @FormUrlEncoded:设置提交数据编码,不设置会出错
	 */
	@FormUrlEncoded
	@POST("MyServlet")
	public Call<List<User>> login(@Field("username") String uname,
								  @Field("password") String password);

4.2. 调用接口

//http://192.168.168.157:8080/Web001/MyServlet
    public void getJson(View view) {
        Retrofit retrofit2 = new Retrofit.Builder().baseUrl("http://192.168.168.157:8080/Web001/")
                .addConverterFactory(GsonConverterFactory.create()).build();
        LoginService loginService= retrofit2.create(LoginService.class);
        Call<List<User>> users= loginService.login("xiaoming","123");
        users.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                Log.e(TAG,"call:"+response.body());
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {

            }
        });
    }

4.  Retrofit2 配合RxJava2使用:

4.1. 声明接口: LoginService 声明方法

// 发送post请求,retrofit2配合rxjava2使用
	@FormUrlEncoded
	@POST("MyServlet")
	Observable<List<User>> loginRxJava(@Field("username") String uname,
								  @Field("password") String password);

4.2. 调用接口:

   // Retrofit2 和 RxJava 框架开发
    // RxJava2CallAdapterFactory RxJava和
    public void getR2AndRxJava(View view) {
        Retrofit retrofit2 = new Retrofit.Builder().baseUrl("http://192.168.168.157:8080/Web001/")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create()).build();

        LoginService loginService= retrofit2.create(LoginService.class);

        loginService.loginRxJava("xiaoming","123")
             .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<User>>() {
                    @Override
                    public void accept(List<User> users) throws Exception {
                        Log.e("denganzhi1", "rxjava的返回数据:" + users.toString());
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.e(TAG,"错误是:"+throwable);
                    }
                });
    }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值