Android Mvp设计模式结合RxJava+OkHttp+retrofit浅谈

前一段时间撸了好久的webview和前端的代码,停下来时间感觉要学点什么东西,在此和大家分享下我对mvp设计模式的理解,可能很多小伙伴项目中也会用到。先上代码,后面附上个人总结。

View层

/**
 * Created by qiang.lin,view的接口,主要做一些获取用户输入的操作,和界面显示toast,页面跳转。
 */
public interface LoginViewInterface {
    void showMsg(String msg);
    String getUser();
    String getPwd();
    void startIntent();

}
public class LoginActivity extends BaseActivity implements View.OnClickListener, LoginViewInterface {
    @InjectView(R.id.name)
    EditText name;
    @InjectView(R.id.pwd)
    EditText pwd;
    @InjectView(R.id.skip_register)
    TextView skipRegister;
    @InjectView(R.id.forget_pwd)
    TextView forgetPwd;
    @InjectView(R.id.login)
    Button login;

    private LoginPreInterface loginPreInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        MyApplication.getInstance().getActivityManager().addActivity(this);
        ButterKnife.inject(this);
        initView();
        initData();
    }

    @Override
    protected void initData() {

    }

    @Override
    protected void initView() {
        loginPreInterface=new LoginPreImpl(this);
        login.setOnClickListener(this);
        forgetPwd.setOnClickListener(this);
        skipRegister.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.skip_register:
                Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(intent);
                break;
            case R.id.login:
                loginPreInterface.login();
                break;
            case R.id.forget_pwd:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MyApplication.getInstance().getActivityManager().finishActivity(this);
        Log.i("登录界面销毁", "----");
    }

    @Override
    public void showMsg(String msg) {
        Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_LONG).show();
    }

    @Override
    public String getUser() {
        return name.getText().toString();
    }

    @Override
    public String getPwd() {
        return pwd.getText().toString();
    }

    @Override
    public void startIntent() {
        Intent intent=new Intent(LoginActivity.this,MainActivity.class);
        startActivity(intent);
    }

在activity里面实现View的接口,主要做一些用户界面操作,我用了butterknife这个插件,这个大家可以去上网百度,快速实例化控件,并且对每个Activity进行管理。
butterknift使用:
添加依赖 compile ‘com.jakewharton:butterknife:6.1.0’
下载bufferknife就行,在setting里面可以直接下载。

P层

import example.com.mvpdesign.view.interfaces.LoginViewInterface;

/**
 * Created by qiang.lin ,登录功能接口
 */
public interface LoginPreInterface {
    void login();
}
/**
 * Created by qiang.lin 方法回调,成功还是失败
 */
public interface OnLoginListener {
    void onFail();
    void onSucceed();
}

/**
 * Created by qiang.lin,P层的实现类
 */
public class LoginPreImpl implements LoginPreInterface,OnLoginListener {
    private LoginViewInterface loginViewInterface;
    private LoginModel loginModel;


    public LoginPreImpl(LoginViewInterface loginViewInterface) {
        this.loginViewInterface = loginViewInterface;
        loginModel = new LoginModelImpl(this);
    }

    @Override
    public void login() {
        String pwd = loginViewInterface.getPwd();
        String name = loginViewInterface.getUser();
        if(pwd.isEmpty()||name.isEmpty()){
            loginViewInterface.showMsg("用户信息不全");
            return;
        }
        loginModel.login(name, pwd);
    }


    @Override
    public void onFail() {
        loginViewInterface.showMsg("用户名或密码错误");
    }

    @Override
    public void onSucceed() {
        loginViewInterface.startIntent();
       loginViewInterface.showMsg("登录成功");
    }
}

Model层

/**
 * Created by qiang.lin,实体类
 */
public class Entity<T> {
    private int code;
    private T msg;

    public Entity(int code, T msg) {
        super();
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public T getMsg() {
        return msg;
    }

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

}

/**
 * Created by qiang.lin m层的功能接口
 */
public interface LoginModel {
    void login(String name,String pwd);
}

这里开始就要用到网络请求框架和Rxjava。
添加依赖

 compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.okhttp3:okhttp:3.8.1'
    compile 'com.google.code.gson:gson:2.8.1'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
       compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    compile 'io.reactivex.rxjava2:rxjava:2.1.1'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'com.squareup.okhttp3:logging-interceptor:3.8.1'
/**
 * Created by qiang.lin
 */
public class LoginModelImpl implements LoginModel {
    private OnLoginListener onLoginListener;

    public LoginModelImpl(OnLoginListener onLoginListener) {
        this.onLoginListener = onLoginListener;
    }

    @Override
    public void login(String name, String pwd) {
        RxJavaClient.login(name, pwd, new Observer<Entity>() {
            private Disposable disposable;
            private int i;
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                //这里可以判断中断观察者接受数据源,被观察者还是会继续发送剩下数据。
                disposable = d;
            }

            @Override
            public void onNext(@NonNull Entity entity) {
                //网络端发来的请求,disposable会让观察者停止接受数据源,但是被观察者还是会继续发送
                //返回的数据在entity里面
//                i++;
//                if (i == 6) {
//                    disposable.dispose();
//                    Log.d("----", "isDisposed : " + disposable.isDisposed());
//                }
                boolean flag = isMainThread();
                Log.i("----------------是否在主线程上", flag + "");
             //根据网络请求的返回码判断调用成功方法还是失败方法。
                onLoginListener.onSucceed();
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e("rxjava错误日志", e + "");
                onLoginListener.onFail();
            }

            @Override
            public void onComplete() {
                Log.i("-------onComplete", "");
            }
        });
    }

    //判断是否在主线程上
    public boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }


}

在这里要搭建网络请求框架,我就直接上代码了,直接用。

/**
 * Created by qiang.lin
 * 这里要创建一个方法,在retrofitservice也要创建一个方法
 */
//遇到耗时操作的时候可能要做修改,图片、文件、缓存
public class RxJavaClient {
    //创建实例调用
    private static final RetrofitService retrofitService = RetrofitClient.getClient();

    //POST请求
    public static void login(String name, String pwd, Observer<Entity> observer) {
        setSubscribe(retrofitService.login(name, pwd), observer);
    }


    //公共方法
    public static <T> void setSubscribe(Observable<T> observable, Observer<T> observer) {
        observable.subscribeOn(Schedulers.io())
                .subscribeOn(Schedulers.newThread())//子线程访问网络
                .observeOn(AndroidSchedulers.mainThread())//回调到主线程
                .subscribe(observer);
    }

}
/**
 * Created by qiang.lin
 */

public interface RetrofitService {
    //把原来的retrofit的Call回调换成了rxjava的被观察者,跟网络连接就是被观察者
    @Headers("Content-Type:application/json;charset=UTF-8")
    @FormUrlEncoded
    @POST("android/login")
    Observable<Entity> login(@Field("name") String name, @Field("pwd") String pwd);
}

/**
 * Created by qiang.lin 
 */
//单例模式
public class RetrofitClient {
    private static RetrofitService retrofitService;
    private  static final String TAG=RetrofitClient.class.getSimpleName();
    public static RetrofitService getClient() {
        if (retrofitService == null) {
            OkHttpClient okClient = new OkHttpClient();
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            int cacheSize = 10 * 1024 * 1024; // 10 MiB
            Cache cache = new Cache(MyApplication.getInstance().getCacheDir(), cacheSize);//缓存的目录
            OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
                    .connectTimeout(10, TimeUnit.SECONDS)//设置超时时间
                    .readTimeout(10, TimeUnit.SECONDS)//设置读取超时时间
                    .writeTimeout(10, TimeUnit.SECONDS)//设置写入超时时间
                    .addInterceptor(interceptor).addNetworkInterceptor(new Interceptor() {
                        @Override
                        public Response intercept(Chain chain) throws IOException {
                            // 进行重定向等操作
                            //Interceptor的典型使用场景,就是对request和response的Headers进行编辑
                            Response response=chain.proceed(chain.request());
                            Request request = chain.request();
                            long t1 = System.nanoTime();
                            Log.d(TAG,String.format("Sending request %s on %s%n%s",
                                    request.url(), chain.connection(), request.headers()));
                            long t2 = System.nanoTime();
                            Log.d(TAG, String.format("Received response for %s in %.1fms%n%sconnection=%s",
                                    response.request().url(), (t2 - t1) / 1e6d, response.headers(), chain.connection()));
                            Log.i("------------response",response.toString());
                            return response;
                        }
                    })
                    .cache(cache);
            okClient = builder.build();
            Retrofit client = new Retrofit.Builder()
                    //地址
                    .baseUrl(Contants.WEB_URL)
                    .client(okClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//将Callable接口转换成Observable接口
                    .build();

            retrofitService = client.create(RetrofitService.class);
        }
        return retrofitService;
    }
}

到这里一个综合案例就完成了,我基本关键点都有注释,大家可以看看。

总结:1、V层:抽象出获取用户输入和页面更新的接口,实例化P层对象,调用P层的方法,持有
的是P层接口的引用,防止gc回收的时候发现Activity仍持有引用而无法回收,导致oom
2、P层:抽象出具体功能的接口,如Login(interface),然后再Impl方法里面进行实现,
构造器里面传递过来的时候V层的接口class,通过这个来调用V层进行更新。
P层实例化M层的接口,然后调用M层从网络端获取的数据,整合V层过来的数据进行逻辑操作,
操作完成后调用通过接口实例调用V层的更新方法。
3、M层:和mvc里面的M层差不多,调用网络服务,获取数据,把网络服务抽象出来写成工具类。
4、 Android MVP设计模式比较多的采用了多态,通过接口的暴露,让P层持有两个层级的数据,降低了M层和V层的耦合,逻辑操作和视图更新分离,利于单元测试,但是需要些很多个接口类。
做单元测试的时候,可以写一个P层的测试类,这样来测试,因为主要的逻辑操作都在P层,减少了Activity的代码量。
5、真的是接口爆炸,我写了好多的接口,可能到项目大了它的优点就出来了。

以上仅代表博主本人的个人见解,如果不恰当的地方,可留言纠正。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OkHttpRxJavaRetrofit是个非常常用的组合,用来进行网络请求和处理。 首先,OkHttp是一个开源的HTTP客户端,提供了简洁的接口,用于与服务器进行通信,并且支持HTTP/2协议,拥有连接池、请求重试和缓存等功能。 然后,RxJava是一个基于观察者模式的异步编程库,可以用于处理异步操作,如网络请求、文件IO等。它的核心是Observable(被观察者)和Subscriber(订阅者),通过各种操作符可以对数据进行变换和处理。 最后,Retrofit是一个RESTful风格的HTTP请求库,它基于OkHttp,使用了Retrofit的注解和接口定义的方式,可以方便地进行网络请求。它支持动态代理,可以将网络请求接口转化为对应的HTTP请求,支持同步和异步请求,并且可以将响应数据转化为Java对象。 综上所述,我们可以使用OkHttp作为底层网络库,然后结合RxJavaRetrofit进行网络请求和数据处理。使用Retrofit的注解和接口定义方式,可以简化网络请求的代码,并且通过RxJava的操作符可以对请求结果进行变换和处理,使得代码更加清晰和可读性。 在使用过程中,可以先创建一个Retrofit实例,并指定OkHttpClient作为网络客户端,然后定义一个接口,在该接口中使用Retrofit的注解,定义网络请求的方法。最后,通过创建该接口的实例,即可进行网络请求,并结合RxJava进行操作。 总之,使用OkHttpRxJavaRetrofit组合进行网络请求可以提高效率和可读性,并且可以处理各种复杂的网络场景,是一种非常实用的方式。 ### 回答2: OKHTTPRXJavaRetrofitAndroid开发中常用的三个库,可以一起使用来进行网络请求和数据处理。 OKHTTP是一个用于处理网络请求的库,可以发送HTTP请求并获取服务器返回的数据。它提供了简洁的API和高效的网络堆栈,可以很好地处理网络请求。我们可以使用OKHTTP来发送SOAP请求到WebService,并获得响应。 RXJava是一个流编程库,它提供了一种被观察者和观察者模式,可以简化异步操作和事件处理。我们可以使用RXJava来处理OKHTTP返回的响应数据,在主线程或后台线程中进行处理,实现数据的异步处理和流式编程。 Retrofit是一个基于OKHTTP的RESTful风格的网络请求库,它提供了一种简洁的方式来定义和发送HTTP请求,并将响应转换为可用的Java对象。我们可以使用Retrofit来定义WebService接口,然后使用注解来指定请求方法、路径和参数,Retrofit会自动帮我们处理请求和响应。 通过OKHTTP的原生支持、RXJava的异步处理和Retrofit的网络请求,我们可以很方便地使用OKHTTPRXJavaRetrofit一起发送WebService请求。首先,我们可以使用Retrofit定义WebService接口,再使用RXJava来处理OKHTTP返回的响应数据,实现简洁高效的网络请求和数据处理。 综上所述,OKHTTPRXJavaRetrofitAndroid开发中常用的网络请求库,它们能够很好地协作,实现对WebService的请求和响应的处理。通过使用它们,我们可以简化网络请求的编写,并实现高效的数据处理。 ### 回答3: OkHttpRxJavaRetrofit是三个在Android开发中常用的网络请求库,它们在一起能够提供更加便捷和高效的网络请求处理。 首先,OkHttp是一个开源的HTTP客户端,它能够处理网络请求、连接管理、请求重试等一系列的网络相关事务。它的特点是简单易用、性能优越、可定制性强。我们可以通过使用OkHttp来发送和接收基于HTTP的请求响应,并进行网络请求的管理和处理。 其次,RxJava是一个响应式编程框架,它基于观察者模式和函数式编程的思想,提供了一系列强大的操作符和线程切换的能力。我们可以使用RxJava来处理异步任务,加快网络请求的响应时间,并且提供方便的线程切换和错误处理机制。 最后,Retrofit是一个RESTful风格的网络请求框架,它结合OkHttpRxJava的强大功能。它提供了一种简单的方式来定义和处理RESTful API的请求和响应。我们可以使用Retrofit来创建和处理webservice的请求,根据API的接口定义来发送请求,并将返回的结果映射到Java对象中。 综上所述,使用OkHttpRxJavaRetrofit能够方便地进行webservice的网络请求,并在处理过程中提供更好的性能和便利性。这三个库的结合能够大大简化网络请求的开发工作,提高开发效率,并提供更好的用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值