一、OkHttp
首先我们需要去到官网查看如何引入okHttp
如图所示,将以下内容加入到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:Retrofit
我这里使用的是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() {
}
});
}