您的位置:首页 > 理论基础 > 计算机网络

Android RxJava+Retrofit+okhttp异步网络加载框架

2018-03-19 15:37 681 查看
RxJava:   一个在Java  vm上使用可观测的序列来组成异步的,基于事件的程序的库。(这是github上的翻译)   现在,这个Rxjava框架基本上取代了AsyncTask和Handler, 因为AsyncTask和handler的异步加载会随着逻辑的加深,变得越来越复杂(指的是逻辑),而RxJava不会,RxJava是通过一种扩展的观察者模式来实现的,Observabl(被观察者)Observer(观察者) 鼠标subscribe(订阅者) 通过这三个步骤来实现的,下面我将列出代码:就可以清晰看到了。Retrofit:    这是一个不错的网络加载库,就是对Okhttp的再次封装。Retrfit与OKhttp共同出资square公司,与OK不同的事retrfit需要定义一个接口,用来返回我们的call对象,retrfit提供的请求方式为注解方式,有get和post。参数也是注解的方式,retrfit是square公司开源的一个高质量高效率的http库,它将我们自己开发的底层代码和细节封装了起来。该项目所需要的依赖包:compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'io.reactivex:rxjava:1.1.6'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'

请求方法注解:

该类型的注解用于标注不同的http请求方式,主要有以下几种:
注解说明
@GET表明这是get请求
@POST表明这是post请求
@PUT表明这是put请求
@DELETE表明这是delete请求
@PATCH表明这是一个patch请求,该请求是对put请求的补充,用于更新局部资源
@HEAD表明这是一个head请求
@OPTIONS表明这是一个option请求
@HTTP通用注解,可以替换以上所有的注解,其拥有三个属性:method,path,hasBody

请求参数类注解:

该类型的注解用来标注请求参数的格式,有些需要结合上面请求和响应格式的注解一起使用。
名称说明
@Body多用于post请求发送非表单数据,比如想要以post方式传递json格式数据
@Filed多用于post请求中表单字段,Filed和FieldMap需要FormUrlEncoded结合使用
@FiledMap和@Filed作用一致,用于不确定表单参数
@Part用于表单字段,Part和PartMap与Multipart注解结合使用,适合文件上传的情况
@PartMap用于表单字段,默认接受的类型是Map
CaipuApi(retorfit必须提供一个接口类,泛型可为String,可为Bean),@Query表示请求参数,将会以key=value(@Query注解参数名称为key,调用传进来的值为value)的方式拼接在url后面.
import java.util.HashMap;

import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import rx.Observable;

public interface CaipuApi {
@POST("/cook/query.php")
Observable<CaiPu> getCaiPu(@QueryMap HashMap<String ,String> map);
}
CaiPu
import java.util.List;

public class CaiPu {
//里面的参数我就不写了,其实这就是一个bean类,你想写什么样的参数就写什么样的参数,
// 根据你自己的需求
}RxJavaRetrofitUtils(网络操作的一个工具类)
在这里面提供了一个baseUrl();方法,这个方法是存放端口号的,多数项目中会出现用到多个BaseUrl的情况,而Retrofit未提供实时切换BaseUrl的方法,且我们在使用Retrofit以及OkHttp时,通常使用单例模式创建Retrofit和OkHttpClient,也不可能每个请求都创建一个Retrofit实例。面对这个实际问题,我们需要做的不仅仅是解决当前问题,更应该从根本上解决该问题,即实现任何情况下的自动切换BaseUrl。
//添加Headers:使用同样的键url_name;使用不同值user或pay,对应账户服地址和支付服地址。下同。
@Headers({"url_name:user"})
@POST("user/login")
Observable<jsonobject> login(@QueryMap Map<string, object=""> paramMap);

@Headers({"url_name:user"})
@POST("user/register")
Observable<jsonobject> register(@QueryMap Map<string, object=""> paramMap);

@Headers({"url_name:pay"})
@POST("pay/getorder")
Observable<jsonobject> getOrder(@QueryMap Map<string, object=""> paramMap);

@Headers({"url_name:pay"})
@POST("pay/payment")
Observable<jsonobject> payment(@QueryMap Map<string, object=""> paramMap);
</string,></jsonobject></string,></jsonobject></string,></jsonobject></string,></jsonobject>
上面是解决的办法。。
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class RxJavaRetorfitUtils {
private static RxJavaRetorfitUtils utils=new RxJavaRetorfitUtils();
CaipuApi caipuApi;
public static RxJavaRetorfitUtils getInstens(){
return utils;
}
public RxJavaRetorfitUtils(){
OkHttpClient client=new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS)
.build();
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://apis.juhe.cn/")
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
caipuApi = retrofit.create(CaipuApi.class);
}
//提供的方法让使用者去调用
public void getCaiPu(HashMap map, final CallBack call){
Observable<CaiPu> caipu=caipuApi.getCaiPu(map);
//调度线程
caipu.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<CaiPu>() {
@Override
public void call(CaiPu caiPu) {
//可以在里面进行操作
if(null==caiPu){
call.onError();
}else{
call.onSuccess(caiPu);
}
}
});
}
//这是一个回调借口
public interface CallBack{
void onSuccess(CaiPu caiPu);
void onError();
}
}
MainActivity
我的这个数据是在聚合数据上请求的接口,就是菜谱大全接口,由于这个接口有点击次数限制,我就不提供给大家了。把你在聚合数据申请接口的key值,填写上面就行了。import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPostUrl();
}
private void initPostUrl() {
HashMap<String,String> map=new HashMap<>();
map.put("menu","土豆丝");
map.put("key","请输入你请求的key值");
RxJavaRetorfitUtils.getInstens().getCaiPu(map, new RxJavaRetorfitUtils.CallBack() {
@Override
public void onSuccess(CaiPu caiPu) {
           Toast.makeText(MainActivity.this, caiPu.toString(), Toast.LENGTH_SHORT).show();
}

@Override
public void onError() {
Log.e("aaaa","打印失败");
}
});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: