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","打印失败");
}
});
}
}