本文参考的链接:参考链接
一、准备工作
1、 首先在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
2、在res文件夹下创建xml文件夹,再在xml文件夹下新建一个.xml文件,文件名可以任取,这里我把名字取为network.xml。然后在该文件中添加如下代码:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
完成之后,在AndroidManifest.xml的application标签中添加下列代码:
android:networkSecurityConfig="@xml/network"
如果跳过这一步,可能会出现CLEARTEXT错误,具体参考该链接
3、在build.gradle添加依赖
//rxjava
implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.squareup.okhttp3:okhttp:3.1.2'
二、创建接收服务器返回类型的类
本文使用的api地址是:http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world
打开它,会发现它返回的字段有status和content,其中content又包含了:from,to,vendor,out,err_no5个字段。据此我们建立接受服务器返回类型的类Translation.java.代码如下:
public class Translation implements Serializable {
@SerializedName("status")
int status;
@SerializedName("content")
Content content;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
@Override
public String toString(){
return content+" "+status;
}
}
@SerializedName中的参数要与api返回的参数名对应上。一般来说要重写toString()方法,和各字段的getter和setter。这里因为Content包含了5个字段,我们还需要再写一个Content类。
Content.java:
public class Content implements Serializable {
@SerializedName("from")
String from;
@SerializedName("to")
String to;
@SerializedName("vendor")
String vendor;
@SerializedName("out")
String out;
@SerializedName("err_no")
int err_no;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public String getOut() {
return out;
}
public void setOut(String out) {
this.out = out;
}
public int getErr_no() {
return err_no;
}
public void setErr_no(int err_no) {
this.err_no = err_no;
}
@Override
public String toString(){
return from+" "+to+" "+vendor+" "+out+" "+err_no;
}
}
三、创建用于描述网络请求的接口类
public interface ClientApi {
@GET("ajax.php?a=fy&f=auto&t=auto&w=hello%20world")
Observable<Translation> getTranslation();
}
@GET里的内容的含义下文再解释。
四、使用Retrofit和RxJava
在MainActivity的onCreate中
首先创建Retrofit实例:
OkHttpClient.Builder builder=new OkHttpClient.Builder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(9,TimeUnit.SECONDS);
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://fy.iciba.com/")//这个URL加上ClientApi中的GET注解括号内的内容就凑成了一个完整的URL
.client(builder.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())//设置服务返回后数据的解析器,这里采用的是Gson解析器
.build();
这里baseUrl中的参数与之前API中@GET中的string连接起来就是一个完整的可访问的url了。
ClientApi api=retrofit.create(ClientApi.class);
Observable<Translation> TranslationObservable=api.getTranslation();
TranslationObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())//消费数据选择在主线程执行,因为主线程才能做更新UI的操作
.subscribe(new Observer<Translation>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Translation translation) {
TRANSLATION.setText(translation.content.toString());
Log.i("MainActivity","连接成功");
}
@Override
public void onError(Throwable e) {
Log.i("MainActivity","连接失败"+e.getMessage());
}
@Override
public void onComplete() {
}
});
这里将获取的结果显示在TextView上。
这里用retrofit实例创建了api的实例,调用api.getTranslation()方法获取数据。
TranslationObservable.observeOn(AndroidSchedulers.mainThread()),原因是只有在主线程才能更新UI的操作
这样就完成了一个从api获取信息的demo