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