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

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 getCaiPu(@QueryMap HashMap 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 login(@QueryMap Map paramMap);

    @Headers({"url_name:user"})
    @POST("user/register")
    Observable register(@QueryMap Map paramMap);

    @Headers({"url_name:pay"})
    @POST("pay/getorder")
    Observable getOrder(@QueryMap Map paramMap);

    @Headers({"url_name:pay"})
    @POST("pay/payment")
    Observable payment(@QueryMap Map paramMap);

上面是解决的办法。。

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=caipuApi.getCaiPu(map);
        //调度线程
        caipu.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1() {
                    @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 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","打印失败");
            }
        });
    }
}

 

你可能感兴趣的:(Android)