Uno, OkHttp
Primero tenemos que ir al sitio web oficial para ver cómo presentar okHttp
https://square.github.io/okhttp/#releases
Como se muestra en la figura, agregue el siguiente contenido al archivo build.gradle y luego haga clic en el botón de sincronización en la parte superior derecha, de modo que hayamos introducido la dependencia de okHttp
implementation("com.squareup.okhttp3:okhttp:4.9.0")
Si encuentra un error al iniciar: La clase module-info no tiene un super tipo. Por favor, baje la versión de okhttp, la he reducido a 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);
}
}
});
}
}
Defina un botón en la página, después de hacer clic en él, envíe una solicitud de obtención al fondo
<?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>
Obtener datos de fondo con éxito
Enviar solicitud de publicación
Publique el formulario en segundo plano
//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);
}
}
});
}
Recibir código en segundo plano
La publicación envía la cadena Json al fondo
//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);
}
}
});
}
Reciba el código en segundo plano, aquí preste atención para agregar un @RequestBody para recibir el objeto de cadena Json
Dos, modernización
Seguimos yendo al sitio web oficial para averiguar cómo presentar Retrofit: https://square.github.io/retrofit/#download
Estoy usando la versión 2.9.0 aquí
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
Primero defina una clase de interfaz
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);//直接返回实体类
}
Luego use Retrofit para solicitar datos de antecedentes
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());
}
});
}
}
Podemos encontrar que el resultado que obtenemos cada vez es una cadena. ¿Qué pasa si queremos obtener el objeto directamente?
Primero introducimos una dependencia gson
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
Entonces modifique el método init ahora mismo
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("失败");
}
});
}
Tres, RxJava
RxJava: una biblioteca que implementa operaciones asincrónicas
Lo mismo se hace de forma asincrónica, ¿por qué la gente lo usa en lugar de AsyncTask / Handler / ...? A medida que la lógica del programa se vuelve cada vez más compleja, aún se puede mantener simple (consulte: https://gank.io/post/560e15be2dca930e00da1083 )
Por ejemplo, al cargar varias imágenes:
Lógica de llamada común:
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();
Utilice la lógica de llamada de RxJava:
Esta implementación de RxJava es una llamada encadenada de arriba a abajo sin ningún anidamiento, lo que es ventajoso en términos de simplicidad lógica. Cuando los requisitos se vuelvan más complejos, esta ventaja será más obvia (Imagínese si todavía necesita seleccionar solo las primeras 10 imágenes, ¿qué haría de la manera convencional? ¿Y si hubiera más requisitos como este? Simplemente piénselo de nuevo, en Esta gran cantidad de requisitos Después de dos meses de implementación, debe cambiar la función. Cuando regrese aquí y vea la sangría del rompecabezas que escribió, puede garantizar que lo entenderá rápidamente, en lugar de repensar el código.
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);
}
});
A continuación lo uso con Rxjava
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
Agregar método en ApiService
@GET("/test")
Observable<BaseInfoModel> getInfo5(@Query("cccc") String cccc);
transferir
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() {
}
});
}