Android network programming-the use of OkHttp

One, OkHttp

 

First we need to go to the official website to see how to introduce okHttp 

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

 As shown in the figure, add the following content to the build.gradle file, and then click the synchronization button at the top right, so that we have introduced the dependency of okHttp

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

 If you encounter an error during startup: Class module-info is missing a super type. Please reduce the version of okhttp, I will reduce it to 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);
                }
            }
        });
    }
}

 Define a button on the page, after clicking it, send a get request to the background

<?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>

Successfully get background data 

 

Send Post request

Post the form to the background

//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);
                }
            }
        });
    }

Receive code in the background 

Post sends the Json string to the background

//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);
                }
            }
        });
    }

Receive the code in the background, here pay attention to add a @RequestBody to receive the Json string object 

 

 

Two, Retrofit

We still go to the official website to find out how to introduce Retrofit: https://square.github.io/retrofit/#download

I am using version 2.9.0 here

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

 First define an interface class

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);//直接返回实体类

}

Then use Retrofit to request background data 

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());
            }
        });
    }
}

We can find that the result we get every time is a string. What if we want to get the object directly?

First we introduce a gson dependency

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

Then modify the init method just now

    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("失败");
            }
        });
    }

 

Three, RxJava

RxJava: A library that implements asynchronous operations

The same is done asynchronously, why do people use it instead of the ready-made AsyncTask / Handler / ...? As the program logic becomes more and more complex, it can still be kept simple (refer to: https://gank.io/post/560e15be2dca930e00da1083 )

For example, when loading multiple pictures:

Common call logic:

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();

 Use RxJava's calling logic:

This implementation of RxJava is a chain call from top to bottom without any nesting, which has advantages in logical simplicity. When the requirements become more complex, this advantage will be more obvious (Imagine if you still need to select only the first 10 pictures, what would you do in the conventional way? What if there are more requirements like this? Just think again, in this large number of requirements After two months of implementation, you need to change the function. When you turn back here and see the indentation of the puzzle that you wrote, you can guarantee that you will understand it quickly, instead of rethinking the code.

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);
        }
    });

Below I use it with Rxjava

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

Add method in ApiService 

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

 transfer

    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() {

                    }
                });
    }

 

Guess you like

Origin blog.csdn.net/hzkcsdnmm/article/details/112277680