Retrofit2.X+RxJava2.X + MVP实现网络请求

最近刚接触RxJava,结合Retrofit在加上MVP模式来实现网络请求。代码是技术的一种实现,但更重要的是思想。Retrofit是基于Okhttp封装的用于网络请求的框架,RxJava与RxAndroid结合使得Android的异步操作更加优雅,易于维护。接下来通过实现一个用户的登陆功能,接收服务端返回的数据,来判断是否登陆成功。下面简要说明一下我的思路:,

一、.添加依赖的各种库。

二、创建接收网络返回的实体类,用于解析网络请求结果。

三、根据返回数据类型,创建网络请求接口,通过RxJava的Observable(被观察者)处理网络返回数据,创建网络请求功能。

四、创建MVP模式,分别处理不同层面的逻辑功能,即通过接口来实现数据从  V —》P—》M —》服务器,在将数据从服务器—》M—》P—》V的传递。

第3、4步才是核心部分。下面依次来实现一下

一、添加依赖的各种库

    //retrofit 系列库
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    //retrofit默认回调的适配器
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    //gson转换器  convert  Gson
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

    //Rxjava2 系列库
    //Rxandroid
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    //RxJava  使用Rxjava2需要依赖的库
    implementation 'io.reactivex.rxjava2:rxjava:2.2.3'

二、创建接收网络返回的实体类,用于解析网络请求结果。

创建接收数据的实体类LoginResult.ava

public class LoginResult {
    /*String aa = "data : {\"token\":\"eyJ1c2VybmFtZSI6ICJ4dXNodW4iLCAiZXhwIjogIjIwMTctMDctMjMgMDY6NTc6MTIifQ==\"}";*/
    private int success;
    private String msg;
    private DataBean dataBean;

    public int getSuccess() {
        return success;
    }

    public void setSuccess(int success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public DataBean getDataBean() {
        return dataBean;
    }

    public void setDataBean(DataBean dataBean) {
        this.dataBean = dataBean;
    }

    public class DataBean{
        private String token;

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }
    }
}

三、 根据返回数据类型,创建网络请求接口

1.此处才是将RxJava与Retrofit关联起来的关键。见ApiInterfaceService.java

/**
 * Author : Zmj
 * Blog : https://blog.csdn.net/Zmj_Dns
 * DitHub : https://github.com/ZmjDns
 * Time : 2019/1/24
 * Description :用于请求网络的接口
 */
public interface ApiInterfaceService {
    @POST("?action=login")
    @FormUrlEncoded
    Observable<LoginResult> loginByObservablePost(@FieldMap Map<String, RequestBody> paramsBody);
    //网络请求作为被观察者,用Observable来声明
}

 2.创建Retrofit网络请求单例,见RetrofitClientSingleton.java

/**
 * Author : Zmj
 * Blog : https://blog.csdn.net/Zmj_Dns
 * DitHub : https://github.com/ZmjDns
 * Time : 2019/1/24
 * Description :Retrofit封装类 单例模式
 */
public class RetrofitClientSingleton {

    private final String TAG = this.getClass().getSimpleName();

    private static  RetrofitClientSingleton retrofitInstance;

    private static final int TIME_OUT = 20;

    private static final String BASR_URL = "http://192.168.1.254:8080/myssm/";

    private Retrofit myRertofit;
    public final ApiInterfaceService myApiService;

    public static RetrofitClientSingleton getInstance() {
        if (retrofitInstance == null){
            synchronized (RetrofitClientSingleton.class){
                if (retrofitInstance == null){
                    retrofitInstance = new RetrofitClientSingleton();
                }
            }
        }
        return retrofitInstance;
    }


    private RetrofitClientSingleton() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);

        myRertofit = new Retrofit.Builder()
                .baseUrl(BASR_URL)            //基础URL
                .client(builder.build())      //配置OkHttp的配置
                .addConverterFactory(GsonConverterFactory.create()) //数据转换
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  //网络请求适配
                .build();

        //获取APiService对象,用于请求网络
        myApiService = myRertofit.create(ApiInterfaceService.class);
    }
}

四、MVP模式实现

1.创建View接口,用于Vie与Presenter数据传递,见IView.java

public interface IView {
    void showLoading();
    //用于显示数据
    void showData(LoginResult result);
}

2.创建Model接口,用于Model与Presenter之间数据传递,见IModel.java

public interface IModel {
    //被观察者,此处引入RxJava的被观察者
    Observable<LoginResult> login(String name,String psd,Observer<LoginResult> observer);
}

3. Model实现IModel,进行网络请求,见LoginModel.java

/**
 * Author : Zmj
 * Blog : https://blog.csdn.net/Zmj_Dns
 * DitHub : https://github.com/ZmjDns
 * Time : 2019/1/24
 * Description :
 */
public class LoginModel implements IModel {

    private final String TAG = this.getClass().getSimpleName();

    @Override
    public Observable<LoginResult> login(String name, String psd,Observer<LoginResult> observer) {
        //对View曾传来的数据处理
        Map<String, RequestBody> paramsBody = new HashMap<>();
        RequestBody rbname = RequestBody.create(MediaType.parse("text/plain"),name);
        RequestBody rbPsd = RequestBody.create(MediaType.parse("text/plain"),psd);
        paramsBody.put("name",rbname);
        paramsBody.put("password",rbPsd);

        //被观察者执行网络请求
        return Observable.create(new ObservableOnSubscribe<LoginResult>() {
            @Override
            public void subscribe(ObservableEmitter<LoginResult> emitter) throws Exception {
                //获取ApiInterfaceService对象
                RetrofitClientSingleton.getInstance().myApiService.loginByObservablePost(paramsBody)
                        .subscribeOn(Schedulers.io())       //在子线程中网络请求
                        .observeOn(AndroidSchedulers.mainThread())//在主线程中操作返回结果
                        .subscribe(observer);   //将observable(被观察者)与observer(观察者)关联
            }
        });
    }
}

 4.实现prenster,调度整体逻辑,见LoginPersenter.java

/**
 * Author : Zmj
 * Blog : https://blog.csdn.net/Zmj_Dns
 * DitHub : https://github.com/ZmjDns
 * Time : 2019/1/24
 * Description :
 */
public class LoginPersenter<T extends IView> {

    private final String TAG = this.getClass().getSimpleName();

    //用于持有View的弱引用
    private WeakReference<T> weakReference;

    private LoginModel loginModel = new LoginModel();

    public LoginPersenter() {
    }

    public void onAttach(T view){
        weakReference = new WeakReference<>(view);
    }

    public void detach(){
        weakReference.clear();
    }

    /**
     * 此方法是关键,在View层调用此方法,就完成的数据在不同层之间的传递
     * @param name
     * @param psd
     */
    public void login(String name, String psd){
        if (weakReference.get() != null){
            weakReference.get().showLoading();//UI操作
            if (loginModel != null){
                //此处实现观察者的功能,用于处理网络返回数据
                Observer<LoginResult> observer = new Observer<LoginResult>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: INLOGINPRESENTER");
                    }
                    @Override
                    public void onNext(LoginResult result) {
                        //获取数据在UI操作
                        weakReference.get().showData(result);
                        Log.d(TAG, "onNext: INLOGINPRESENTER" + result.getDataBean().getToken());
                    }
                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: INLOGINPRESENTER" + e.getMessage());
                    }
                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete: INLOGINPRESENTER");
                    }
                };
                //获取Model层请求网络结果的被观察者对象
                Observable<LoginResult> observable = loginModel.login(name,psd,observer);

                //将observable(被观察者)与observer(观察者)关联
                observable.subscribe(observer);
            }
        }
    }
}

5.在Vie层实现Ivew接口,完成网络请求、数据传递 ,见TestRxJandRetrAct2.java

/**
 * Author : Zmj
 * Blog : https://blog.csdn.net/Zmj_Dns
 * DitHub : https://github.com/ZmjDns
 * Time : 2019/1/22
 * Description :
 */
public class TestRxJandRetrAct2 extends AppCompatActivity implements IView {
    
    private final String TAG = this.getClass().getSimpleName();

    private Observer<LoginResult> observer;

    private LoginPersenter loginPersenter; //持有Presenter的引用

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_test_rxjava_retrofit_1);

        loginPersenter = new LoginPersenter();

        loginPersenter.onAttach(this);  //绑定View传到Presenter
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void showData(LoginResult result) {
        Log.d(TAG, "showData: INACTIVITY" + result.getDataBean().getToken());
        Toast.makeText(this,result.getDataBean().getToken(),Toast.LENGTH_SHORT).show();
    }

    //调用此方法,用于网络请求
    public void mvpLogin(View view){
        loginPersenter.login("aaa","123456");
    }

    @Override
    protected void onDestroy() {
        loginPersenter.detach();
        super.onDestroy();
    }
}

 至此完成,整个功能。希望能帮助到大家,有错的地方欢迎拍砖。

至于后台,写的特别简单,见Action.java,在Jsp中引入此类,调用getActions(request)方法即可。

public class Actions {
	private final String TAG = this.getClass().getSimpleName();
			
	public static final String getActions(HttpServletRequest request) {
		try {
			request.setCharacterEncoding("utf-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		String responseText = "";
		
		String action = request.getParameter("action");
		
		if (action.equalsIgnoreCase("login")) {
			System.out.println("开始返回数据");
			responseText = "{\"success\":0,\"msg\":\"aa\",\"dataBean\":{\"token\":\"eyJ1c2VybmFtZSI6ICJ4dXNodW4iLCAiZXhwIjogIjIwMTctMDctMjMgMDY6NTc6MTIifQ==\"}}";
			
		}
		return responseText;
		
	}

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值