Android网络编程——OkHttp的使用

一、OkHttp

首先我们需要去到官网查看如何引入okHttp 

https://square.github.io/okhttp/#releases

 如图所示,将以下内容加入到build.gradle文件内,然后点击右上方的同步按钮,这样我们就引入了okHttp的依赖了

implementation("com.squareup.okhttp3:okhttp:4.9.0")

 如果遇到启动时报错:Class module-info is missing a super type.请降低okhttp的版本,我这里降成了3.5.0就可以了

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Test2Activity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test2);
        init();
    }

    public void init(){
        Button btn=findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                getSync();
                getAsync();
            }
        });
    }

    //同步请求
    public void getSync(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client=new OkHttpClient();
                Request request=new Request.Builder()
                        .get()
                        .url("你的后台地址")
                        .build();
                Call call=client.newCall(request);
                try {
                    //同步发送请求
                    Response response=call.execute();
                    if(response.isSuccessful()){
                        String s=response.body().string();
                        System.out.println("text:"+s);
                        System.out.println("请求成功");
                    }else{
                        System.out.println("请求失败");
                    }
                } catch (IOException e) {
                    System.out.println("error");
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //异步请求
    public void getAsync(){
        OkHttpClient client=new OkHttpClient();
        Request request=new Request.Builder()
                .url("你的后台地址")
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result=response.body().string();
                    System.out.println(result);
                }
            }
        });
    }
}

 页面中定义一个按钮,在点击后去向后台发送一个get请求

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="123"/>

</LinearLayout>

成功得到后台数据 

发送Post请求

Post发送表单到后台

//post-表单
    public void post(){
        OkHttpClient client=new OkHttpClient();
        FormBody body=new FormBody.Builder()
                .add("test1","testValue1")
                .add("test2","testValue2")
                .add("test3","testValue3")
                .build();
        Request request=new Request.Builder()
                .url(url_post)
                .post(body)
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result=response.body().string();
                    System.out.println(result);
                }
            }
        });
    }

后台接收代码 

Post发送Json字符串到后台

//post-JSON字符串
    public void postJson(){
        OkHttpClient client=new OkHttpClient();
        MediaType mediaType=MediaType.parse("application/json;charset=utf-8");
        String jsonStr="{\"test1\":\"test1Value\",\"test2\":\"test2Value\",\"test3\":\"test3Value\"}";
        FormBody body= RequestBody.create();
        Request request=new Request.Builder()
                .url(url_post)
                .post(body)
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result=response.body().string();
                    System.out.println(result);
                }
            }
        });
    }

后台接收代码,这里注意要加一个@RequestBody来接收Json字符串对象 

二、Retrofit

我们还是去到官网去查找如何引入Retrofit:https://square.github.io/retrofit/#download

我这里使用的是2.9.0版本

implementation 'com.squareup.retrofit2:retrofit:2.9.0'

 先定义一个接口类

public interface ApiService {

    @GET("/test")
    Call<ResponseBody> getInfo();//无参数

    @GET("/test/{value}")
    Call<ResponseBody> getInfo4(@Path("value") String value);//路径中带参数

    @GET("/test")
    Call<ResponseBody> getInfo2(@Query("value") String value);//直接传参数

    @GET("/test")
    Call<BaseInfoModel> getInfo3(@Query("value") String value);//直接返回实体类

}

然后使用Restrofit请求后台数据即可 

public class Test3Activity extends AppCompatActivity {

    private String url="http://www.test.com/";

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

    public void init(){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(url)//baseUrl必须以'/'结束
                .build();
        ApiService apiService=retrofit.create(ApiService.class);
        Call<ResponseBody> call=apiService.getInfo();
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                if(response.isSuccessful()){
                    try {
                        String result=response.body().string();
                        System.out.println(result);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else{
                    System.out.println("失败");
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                System.out.println(t.getMessage());
            }
        });
    }
}

我们可以发现我们每次获取的结果都是字符串,如果我们像直接获取到想要的对象呢?

首先我们引入一个gson依赖

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

然后对刚才的init方法进行修改

    public void init(){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(url)//baseUrl必须以'/'结束
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiService apiService=retrofit.create(ApiService.class);
        Call<BaseInfoModel> call=apiService.getInfo3("test");
        call.enqueue(new Callback<BaseInfoModel>() {
            @Override
            public void onResponse(Call<BaseInfoModel> call, Response<BaseInfoModel> response) {
                BaseInfoModel infoModel=response.body();
                System.out.println(infoModel);
            }

            @Override
            public void onFailure(Call<BaseInfoModel> call, Throwable t) {
                System.out.println("失败");
            }
        });
    }

三、RxJava

RxJava:一个实现异步操作的库

同样是做异步,为什么人们用它,而不用现成的 AsyncTask / Handler / ... ?随着程序逻辑变得越来越复杂,它依然能够保持简洁(参考了:https://gank.io/post/560e15be2dca930e00da1083

比如加载多张图片时:

普通调用逻辑:

new Thread() {
    @Override
    public void run() {
        super.run();
        for (File folder : folders) {
            File[] files = folder.listFiles();
            for (File file : files) {
                if (file.getName().endsWith(".png")) {
                    final Bitmap bitmap = getBitmapFromFile(file);
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            imageCollectorView.addImage(bitmap);
                        }
                    });
                }
            }
        }
    }
}.start();

 使用RxJava的调用逻辑:

RxJava 的这个实现,是一条从上到下的链式调用,没有任何嵌套,这在逻辑的简洁性上是具有优势的。当需求变得复杂时,这种优势将更加明显(试想如果还要求只选取前 10 张图片,常规方式要怎么办?如果有更多这样那样的要求呢?再试想,在这一大堆需求实现完两个月之后需要改功能,当你翻回这里看到自己当初写下的那一片迷之缩进,你能保证自己将迅速看懂,而不是对着代码重新捋一遍思路

Observable.from(folders)
    .flatMap(new Func1<File, Observable<File>>() {
        @Override
        public Observable<File> call(File file) {
            return Observable.from(file.listFiles());
        }
    })
    .filter(new Func1<File, Boolean>() {
        @Override
        public Boolean call(File file) {
            return file.getName().endsWith(".png");
        }
    })
    .map(new Func1<File, Bitmap>() {
        @Override
        public Bitmap call(File file) {
            return getBitmapFromFile(file);
        }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Bitmap>() {
        @Override
        public void call(Bitmap bitmap) {
            imageCollectorView.addImage(bitmap);
        }
    });

下面我配合Rxjava来使用

 implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'

ApiService中添加方法 

@GET("/test")
Observable<BaseInfoModel> getInfo5(@Query("cccc") String cccc);

 调用

    public void init(){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(url)//baseUrl必须以'/'结束
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        ApiService apiService=retrofit.create(ApiService.class);
        apiService.getInfo5("test")
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<BaseInfoModel>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(BaseInfoModel value) {
                        System.out.println(value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

猜你喜欢

转载自blog.csdn.net/hzkcsdnmm/article/details/112277680