MVP+Rxjava2+Retrofit2-初学者demo

最近刚刚学完MVP+Rxjava2+Retrofit2,于是迫不及待的想写个demo,也希望可以帮助和我一样的新人学这些技术(刚入门的时候还是挺难的),demo使用了聚合数据获取新闻信息

 

来看一下demo的效果:

 

推荐几位大神的文章,希望对小伙伴学习这些有帮助:

Android Gilde教程       https://blog.csdn.net/qq_32368129/article/details/69526148

这可能是最好的RxJava 2.x 教程        http://www.apkbus.com/blog-898535-68185.html

Android之ButterKnife用法详解       https://blog.csdn.net/leavessilent/article/details/60872096

Android MVP开发模式 google 官方Mvp架构详解          https://blog.csdn.net/jungle_pig/article/details/65626469

这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)  https://blog.csdn.net/carson_ho/article/details/73732076

 

("▔□▔),写了这么多好像还是没有进入正轨,是时候来操作一波了(ノ>▽<。)ノ

 

Gradle配置

    //RecyclerView 
    compile 'com.android.support:design:26.+'      

    //Rxjava2
    compile"io.reactivex.rxjava2:rxjava:2.1.1"
    compile'io.reactivex.rxjava2:rxandroid:2.0.2'

    //Retrofit2
    compile'com.squareup.retrofit2:retrofit:2.3.0'
    compile'com.squareup.retrofit2:converter-gson:2.3.0'
    compile'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

    // okHttp
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'

    //Gilde
    compile 'com.github.bumptech.glide:glide:3.7.0'

    //CradView
    compile 'com.android.support:cardview-v7:26.+'

    //Butterkinfe
    compile 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

项目结构:

                                                                       项目结构参考上方提供的谷歌官方MVP项目结构

第一步创建BaseView和BasePresenter,我这里的BasePresenter接口实际上没用到什么东西,是空的所以就不贴出来了

package com.example.administrator.mvpdemo;

/**
 * Created by Administrator on 2018/9/8.
 */

public interface BaseView {
    void showLodading();
    void  dimissLoading();
}

第二步创建一个MainContract,用于管理BaseView和BasePresenter接口

package com.example.administrator.mvpdemo.Presenter.Contract;

import com.example.administrator.mvpdemo.BaseView;
import com.example.administrator.mvpdemo.Bean.ResultBean;
import com.example.administrator.mvpdemo.Presenter.BasePresenter;

import java.util.List;

/**
 * Created by Administrator on 2018/9/8.
 */

public interface MainContract {
    interface Presenter extends BasePresenter{
        //实现请求数据
       void   requestData();
    }
    interface View extends BaseView{
        void  showResult(List<ResultBean.DataBean> datas);  //显示数据
        void showNodata();  //没有数据
        void showError(String msg);//出现错误
    }
}

第三步准备解析数据的实体类

package com.example.administrator.mvpdemo.Bean;

import java.util.List;

/**
 * Created by Administrator on 2018/9/9.
 */

public class NewsBean<T> {

    private String reason;
    private T result;

    private int error_code;

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public T getResult() {
        return result;
    }

    public void setResult(T result) {
        this.result = result;
    }

    public int getError_code() {
        return error_code;
    }

    public void setError_code(int error_code) {
        this.error_code = error_code;
    }


}

还有一个ResultBean,由于篇幅问题就不贴出来了,GsonFormat一下就行,源码最后会提供下载的

第四步创建 用于描述网络请求 的接口

package com.example.administrator.mvpdemo.Data;

import com.example.administrator.mvpdemo.Bean.NewsBean;
import com.example.administrator.mvpdemo.Bean.ResultBean;

import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;

/**
 * Created by Administrator on 2018/9/9.
 */
//  创建 用于描述网络请求 的接口
public interface ApiService {
    public static final String Base_url="http://v.juhe.cn/toutiao/";

    @GET("index")
    Observable <NewsBean<ResultBean>> getApp(@Query("typ") String type,@Query("key") String key);
}

第五步创建Retrofit实例

package com.example.administrator.mvpdemo.Data;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by Administrator on 2018/9/9.
 */

public class httpManger {

    public OkHttpClient getOkhttp(){

        // log用拦截器
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();

        // 开发模式记录整个body,否则只记录基本信息如返回200,http协议版本等
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        // 如果使用到HTTPS,我们需要创建SSLSocketFactory,并设置到client
//        SSLSocketFactory sslSocketFactory = null;

        return new OkHttpClient.Builder()
                // HeadInterceptor实现了Interceptor,用来往Request Header添加一些业务相关数据,如APP版本,token信息
//                .addInterceptor(new HeadInterceptor())
                .addInterceptor(logging)
                // 连接超时时间设置
                .connectTimeout(10, TimeUnit.SECONDS)
                // 读取超时时间设置
                .readTimeout(10, TimeUnit.SECONDS)

                .build();
    }
   // 创建 Retrofit 实例
    public Retrofit getRetrofit(OkHttpClient okHttpClient){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(ApiService.Base_url)        //添加url地址
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build();
        return retrofit;
    }
}

第六步实现model层逻辑

package com.example.administrator.mvpdemo.Model;

import com.example.administrator.mvpdemo.Bean.NewsBean;
import com.example.administrator.mvpdemo.Bean.ResultBean;
import com.example.administrator.mvpdemo.Data.ApiService;
import com.example.administrator.mvpdemo.Data.httpManger;

import io.reactivex.Observable;

/**
 * Created by Administrator on 2018/9/8.
 */
//model用于提供数据支持模型
public class UseInfoModel {

    public Observable<NewsBean<ResultBean>> getNews(){
        // 步骤五  创建 网络请求接口实例
        httpManger  manger=new httpManger();
        ApiService apiService= manger.getRetrofit(manger.getOkhttp()).create(ApiService.class);

        //步骤六 实现异步请求
        return apiService.getApp("top","bc0a3a53be1e97115c2313e638662cae");//实际上这个是Observable<NewBean<ResultBean>>
    }
}

第七步 MainPresenter用于和View层与model层交互

package com.example.administrator.mvpdemo.Presenter;

import com.example.administrator.mvpdemo.Bean.NewsBean;
import com.example.administrator.mvpdemo.Bean.ResultBean;
import com.example.administrator.mvpdemo.Data.ApiService;
import com.example.administrator.mvpdemo.Data.httpManger;
import com.example.administrator.mvpdemo.Model.UseInfoModel;
import com.example.administrator.mvpdemo.Presenter.Contract.MainContract;


import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.internal.observers.SubscriberCompletableObserver;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by Administrator on 2018/9/8.
 */

public class MainPresenter implements MainContract.Presenter {

    MainContract.View mView;
    UseInfoModel model=new UseInfoModel();

    public MainPresenter(MainContract.View mView) {
        this.mView = mView;
    }

    @Override
    public void requestData() {
     mView.showLodading();
      model.getNews()
              .subscribeOn(Schedulers.io())     //被观察者所在线程      io线程
              .observeOn(AndroidSchedulers.mainThread())  //观察者所在线程    主线程
              .subscribe(new Observer<NewsBean<ResultBean>>() {
                  Disposable mDisposable;
                  @Override
                  public void onSubscribe(@NonNull Disposable d) {
                              mDisposable=d;
                  }

                  @Override
                  public void onNext(@NonNull NewsBean<ResultBean> resultBeanNewsBean) {
                             if (resultBeanNewsBean!=null){
                                 mView.showResult(resultBeanNewsBean.getResult().getData());
                             }else {
                                 mView.showNodata();
                             }
                             mView.dimissLoading();
                  }

                  @Override
                  public void onError(@NonNull Throwable e) {
                        mView.dimissLoading();

                  }

                  @Override
                  public void onComplete() {
                       mView.dimissLoading();
                  }
              });


    }
}

最后贴上MainActivity代码

package com.example.administrator.mvpdemo;

import android.app.ProgressDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;

import com.example.administrator.mvpdemo.Adapter.MyRecyclerViewAdapter;
import com.example.administrator.mvpdemo.Bean.ResultBean;
import com.example.administrator.mvpdemo.Presenter.Contract.MainContract;
import com.example.administrator.mvpdemo.Presenter.MainPresenter;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

public  class MainActivity extends AppCompatActivity implements MainContract.View{
    @BindView(R.id.recyclerView)
    RecyclerView mRecyclerView;
    ProgressDialog dialog;
    MyRecyclerViewAdapter adapter;
    MainContract.Presenter presenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        dialog=new ProgressDialog(this);
        presenter=new MainPresenter(this);
        initData();
    }

    private void initData() {
        presenter.requestData();
    }

    @Override
    public void showLodading() {
        dialog.show();
    }

    @Override
    public void dimissLoading() {
       if (dialog.isShowing()){
           dialog.dismiss();
       }
    }

    @Override
    public void showResult(List<ResultBean.DataBean> datas) {
       initRecycler(datas);
    }

    private void initRecycler(List<ResultBean.DataBean> datas) {
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
        adapter=new MyRecyclerViewAdapter(this,datas);
        mRecyclerView.setAdapter(adapter);
    }

    @Override
    public void showNodata() {
        Toast.makeText(this,"服务器炸了",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showError(String msg) {
       //这个里面用于判断错误
    }
}

实际上也可以导入Dagger2依赖,不过个人感觉有些难,而且这种小demo用上Dagger2有些画蛇添足的意味吧,但也可以试试,而且这个demo完全可以在加工一下成为一个新闻app毕业设计。

写的感觉不够简洁,希望能够有所帮助吧,哈哈哈(●'◡'●)ノ

附上源码百度云盘链接

 

链接:https://pan.baidu.com/s/1cNBpsl4MQjgmqyuGi7OZ_Q 密码:pny7

升级版文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值