Retrofit+RxJava+OKhttp+RxBus

要说起为什么要用这个东西,主要是因为刚刚开始做项目的时候没有什么框架的概念,对代码质量的要求也不高,完全就是为了赶进度,所以写出来的代码可读性差,也在于最近项目没什么需求了,所以想着把代码重构一下,让他至少看上去很美。
看来看去还是先重构网络请求这一块吧,以前网络这块用的是Volley,Volley确实很简单,封装的非常不错,项目里面的网络请求是完全可以满足的,唯一的不好就是感觉会慢一些。
这个只说说在项目中怎么用,想知道原理的同学可以去看看流程。
先说说Refrofit吧,我们要写一个接口类,把网络请求管理起来

public interface HttpServiceApi {
    @POST("user/login")
    Observable<UserBean> getPin(@Body Map<Object, Object> params, @Path("path") String path);
    @POST("{path}/{name}")
    Observable<UserBean> loginCookies(@Body Map<Object, Object> params, @Path("path") String path,@Path("name") String name);
    @POST("{path}/{name}")
    Observable<VersionBean> checkVersion(@Body Map<Object, Object> params, @Path("path") String path, @Path("name") String name);

}

简单说一下把,@POST对应的就是http中的post方法,同样的也有get方法,我们项目中没有使用到get方法,所以这里就没有写get的方法,@Body也就是你要传给服务器的数据,上面的{path}{name}对应下面的方法中的@Path参数,也就是服务端的接口名称,注意在使用@get方法中是不能有@Body的,get方法是不能带Body的。
OK,请求数据接口写好了,然后就是要建立连接了,首先封装Retrofit对应方法:

public class DemoRetrofit {
    public static <T> T create(final Class<T> cls,String webSite,OkHttpClient okHttpClient) {
        Retrofit.Builder builder = new Retrofit.Builder();
        Retrofit retrofit = builder
                .baseUrl(webSite)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)
                .build();
        return retrofit.create(cls);
    }
}

稍微说一下baseUrl就是域名,GsonConverterFactory.create()用来Gson解析,okHttpClient使用OKHttp,主要是为了获得cookies,怎么样获得后面继续
OK,现在开始使用Retrofit,先写一个抽象的BaseActivity

public abstract class BaseActivity extends Activity {
    Observable<String> addOb;
    DemoApiService demoApiService ;
    protected void onCreate(Bundle onSaveStateInstance){
        super.onCreate(onSaveStateInstance);
        demoApiService = DemoRetrofit.create(DemoApiService.class, "http://****.com/****server/", DemoOkHttpClientBuilder.genericClient(getApplicationContext()));
    }
    @Override
    protected void onStart(){
        super.onStart();
        initView();
        initOnClickListener();
    }
    @Override
    protected void onResume(){
        super.onResume();
        addOb = DemoRxBus.get().register("addFeedTag", String.class);
    }
    public abstract void initView();
    public abstract void initOnClickListener();
    @Override
    protected void onStop(){
        super.onStop();
        DemoRxBus.get().unregister("addFeedTag", addOb);
    }
    public void superStatActivity(Intent intent,Bundle bundle){
       startActivity(intent.putExtra("bundleData",bundle));
    }
}

上面的代码清楚的显示了实例化了一个网络请求对象,但是里面有一个DemoOkHttpClientBuilder.genericClient(getApplicationContext()),这是什么鬼东西,看看下面的代码就知道了,

public class DemoOkHttpClientBuilder {
    public static OkHttpClient genericClient(Context context) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(15, TimeUnit.SECONDS);
        builder.interceptors().add(new ReceivedCookiesInterceptor());
        OkHttpClient httpClient = builder.build();
        return httpClient;
    }
}

看了方法名字ok,这个就是给建立的链接一些设置,这里面我只加了超时时间和消息拦截,其他的可以根据需要自己添加,那么这个消息拦截interceptors().add(new ReceivedCookiesInterceptor());干什么用的呢,看看,还是看看代码

public class ReceivedCookiesInterceptor implements Interceptor {
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Response originalResponse = chain.proceed(chain.request());
        List<String> cookieList = originalResponse.headers("Set-Cookie");
        if (cookieList != null) {
            for (String s : cookieList) {
                Log.d("Received" ,"s = " + s);
            }
        }
        return originalResponse;
    }
}

对喽,你想的没错,主要就是为了获得cookies,得到后保存就是你自己的事了。
然后注意到
addOb = DemoRxBus.get().register(“addFeedTag”, String.class);
DemoRxBus.get().unregister(“addFeedTag”, addOb);
这个就是消息通知了,功能相当于EventBus,具体的还是看看代码吧:

public class DemoRxBus {
    private static final String TAG = DemoRxBus.class.getSimpleName();
    private static DemoRxBus instance;
    public static synchronized DemoRxBus get() {
        if (null == instance) {
            instance = new DemoRxBus();
        }
        return instance;
    }
    private DemoRxBus() {
    }
    private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public <T> Observable<T> register(@NonNull Object tag, @NonNull Class<T> clazz) {
        List<Subject> subjectList = subjectMapper.get(tag);
        if (null == subjectList) {
            subjectList = new ArrayList<>();
            subjectMapper.put(tag, subjectList);
        }

        Subject<T, T> subject;
        subjectList.add(subject = PublishSubject.create());
        return subject;
    }
    public void unregister(@NonNull Object tag, @NonNull Observable observable) {
        List<Subject> subjects = subjectMapper.get(tag);
        if (null != subjects) {
            subjects.remove((Subject) observable);
            if (DemoTextUtil.isEmpty(subjects)) {
                subjectMapper.remove(tag);
            }
        }
    }
    public void post(@NonNull Object content) {
        post(content.getClass().getName(), content);
    }
    @SuppressWarnings("unchecked")
    public void post(@NonNull Object tag, @NonNull Object content) {
        List<Subject> subjectList = subjectMapper.get(tag);
        if (!DemoTextUtil.isEmpty(subjectList)) {
            for (Subject subject : subjectList) {
                subject.onNext(content);
            }
        }
    }
}

主要三个方法,注册,取消注册,发送,在现有的工程中网络数据都是回调的没有用到RxBus,想用的同学可以自己用一下。
OK,接下来看看怎么用这些东西去登录吧,

public class DemoActivity extends BaseActivity implements DataListener,View.OnClickListener {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
    }

    @Override
    public void initView() {
        button = (Button)findViewById(R.id.buton);
    }

    @Override
    public void initOnClickListener() {
        button.setOnClickListener(this);
    }

    @Override
    public void dataResponse(DataBean dataBean) {

    }

    @Override
    public void loginResponse(UserBean userBean) {
        UserBean.getInstance().setUserInfo(userBean.getUserInfo());
        Toast.makeText(getApplicationContext(),"token = " +  UserBean.getInstance().getUserInfo().getVideoLength(),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void errorResponse(Throwable e) {
        Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.buton:
                GetDataFromClient dataFromClient = new GetDataFromClient(this);
                Map<Object, Object> params = new HashMap<>();
                params.put("token", "");
                params.put("accountType", "phone");
                params.put("account", "+8611111111111");
                params.put("pin", "1234");
                params.put("jpushId","000270e4cb6");
                params.put("cilentType", 2);
                dataFromClient.getDataFromClientLogin(demoApiService, params);
                break;
        }
    }
}

代码很简单,发送网络请求,用回调函数把返回的数据负责单利的UserBean,这里面的UserBean是用户,用的单例模式。
说了半天都有个RxJava这个东西在哪里呢,你写的这玩意在主线程中用发的网络请求,你这是在搞球啊,别着急,里面不是有个方法嘛
dataFromClient.getDataFromClientLogin(demoApiService, params)看看这个是啥

public class GetDataFromClient {
    DataListener dataListener;

    public GetDataFromClient(DataListener dataListener){
        this.dataListener = dataListener;
    }
    public  void getDataFromClientLogin(DemoApiService demoApiService ,Map<Object, Object> params){
        demoApiService.sendPhoneNumber(params)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<UserBean>() {
                    @Override
                    public void onNext(UserBean userBean) {
                        dataListener.loginResponse(userBean);
                    }
                    @Override
                    public void onCompleted() {

                    }
                    @Override
                    public void onError(Throwable e) {
                        dataListener.errorResponse(e);
                    }
                });
    }
}

看看,就是这个,里面很简单了主线程中观察,新线程中发送网络请求,onNext中回调,好了至此简单的框架就全部搭建完成了。
项目Demo地址:https://github.com/ss831116/DataBindingRxjavaRetrofitApplication.git

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值