Android MVP 的理解

来源:互联网 发布:cp1e编程软件cx one 编辑:程序博客网 时间:2024/05/16 15:16
  • 在android的开发中,MVP肯定都早有听闻,但是真正应用在项目中的是少之又少,因为MVP带来的一个缺点是类的爆炸。
  • 下面简单分析下MVP的结构

mvp结构

从上图分析可以看出,MVP = Model + View + Presenter. Model是专门负责处理数据的请求和接收以及一些处理,而View就是我们的Activity,是专门负责页面的处理,类似页面跳转,显示listview等等,而Presenter就是业务逻辑的处理了,他是协调View和Model之间的中间层。为什么说用了标准的MVP会带来类的爆炸呢?
首先Model需要创建一个interface和一个实现类,View需要一个interface加上Activity,Presenter一个类,而且这些类还不能复用,因为每个activity的逻辑和接口都不一样,对比以前我们自己写Activity的时候,类是从一个变成了5个。要是一个中等的项目。类乘上5倍,那将是想当的可怕。
MVP最初创建的时候是为了给Activity解耦的,而不是用来添堵的。那我们总得想个法子去减少这些类,首先是Model + Presenter.其实在项目中,如何不是很负责的数据,我们完全可以直接在Presenter完成对数据的请求和简单处理,这样我们就可以少了两个类,其次,我们可以用上Retrofit,Retrofit的接口都是interface.我们大可以复用这个类,如果太多,我们增加一个类即可。这样,整个项目中,不会有太多的interface。

下面是简单的代码:Beans-SchoolClass

package rxjava.application.com.androidmyp.Beans;/** * Created by Qiujc on 2016/5/9. */public class SchoolClass extends BaseBean<SchoolClass> {    private int id;    private String className;    private String teacher;    private String grade;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getClassName() {        return className;    }    public void setClassName(String className) {        this.className = className;    }    public String getTeacher() {        return teacher;    }    public void setTeacher(String teacher) {        this.teacher = teacher;    }    public String getGrade() {        return grade;    }    public void setGrade(String grade) {        this.grade = grade;    }    @Override    public String toString() {        return "SchoolClass{" +                "id=" + id +                ", className='" + className + '\'' +                ", teacher='" + teacher + '\'' +                ", grade='" + grade + '\'' +                '}';    }}

Data - ApiCenter 网络接口

package rxjava.application.com.androidmyp.Data;import com.google.gson.JsonObject;import java.util.HashMap;import java.util.List;import retrofit.Call;import retrofit.http.FieldMap;import retrofit.http.FormUrlEncoded;import retrofit.http.POST;import retrofit.http.Query;import rx.Observable;import rxjava.application.com.androidmyp.Beans.BaseBean;import rxjava.application.com.androidmyp.Beans.SchoolClass;import rxjava.application.com.androidmyp.Beans.User;/** * Created by Qiujc on 2016/4/14. * 定义网络的接口 */public interface ApiCenter {    @POST("/user_login")    Observable<BaseBean<User>> UserLogin(@Query("username")String username, @Query("password") String password);    @POST("/user_login")    Call<JsonObject> UserLoginWithRetrofit(@Query("username")String username,@Query("password") String password);    @FormUrlEncoded    @POST("/instalment1.4/api/test/getClassData")    Observable<BaseBean<List<SchoolClass>>> getClass(@FieldMap    HashMap<String,String> hashMap);}

Data-ApiManager 初始化Retrofit

package rxjava.application.com.androidmyp.Data;import com.squareup.okhttp.OkHttpClient;import retrofit.GsonConverterFactory;import retrofit.Retrofit;import retrofit.RxJavaCallAdapterFactory;/** * Created by Qiujc on 2016/4/14. */public class ApiManger {    private static ApiManger apiManger;    public static ApiManger getIntance() {        synchronized (ApiManger.class) {            if (apiManger == null) {                apiManger = new ApiManger();            }        }        return apiManger;    }    public ApiCenter api;    public ApiManger() {        OkHttpClient okHttp = new OkHttpClient();        Retrofit.Builder builder = new Retrofit.Builder();        builder.baseUrl("http://172.16.1.174");        builder.addConverterFactory(GsonConverterFactory.create());        builder.addCallAdapterFactory(RxJavaCallAdapterFactory.create());        builder.client(okHttp);        Retrofit restAdapter = builder.build();        api = restAdapter.create(ApiCenter.class);    }}

View-UserLoginContract–activity的接口

package rxjava.application.com.androidmyp.Login;import rxjava.application.com.androidmyp.Presenter.BaseView;/** * Created by Qiujc on 2016/4/13. */public interface UserLoginContract extends BaseView{    void loginSuccess();    void loginFailed();    void showToast(String msg);}

View-UserLogin —-activity

package rxjava.application.com.androidmyp.Login;import android.content.Intent;import android.os.Bundle;import android.support.design.widget.FloatingActionButton;import android.support.v7.app.ActionBar;import android.support.v7.widget.Toolbar;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import butterknife.Bind;import butterknife.ButterKnife;import rxjava.application.com.androidmyp.BaseActivity;import rxjava.application.com.androidmyp.Home.HomeActivity;import rxjava.application.com.androidmyp.Presenter.LoginPresenter;import rxjava.application.com.androidmyp.R;public class UserLogin extends BaseActivity implements UserLoginContract {    @Bind(R.id.userName)    EditText userName;    @Bind(R.id.passWord)    EditText passWord;    @Bind(R.id.sureToLogin)    Button sureToLogin;    private LoginPresenter loginPresenter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_user_login);        ButterKnife.bind(this);        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);        setSupportActionBar(toolbar);        ActionBar actionBar = getSupportActionBar();        actionBar.setDisplayShowHomeEnabled(true);        //create presenter        this.presenter = new LoginPresenter(this);        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);        fab.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                loginPresenter.getClassInfo();            }        });        sureToLogin.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                loginPresenter.loginWithRetrofit(userName.getText().toString(), passWord.getText().toString());            }        });    }    @Override    public void loginSuccess() {        Toast.makeText(this, "user login success!", Toast.LENGTH_SHORT).show();        startActivity(new Intent(UserLogin.this, HomeActivity.class));        this.finish();    }    @Override    public void loginFailed() {        Toast.makeText(this, "user login Failed!", Toast.LENGTH_SHORT).show();    }    @Override    public void showToast(String msg) {        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();    }    @Override    public void setPresenter(Object presenter) {        this.presenter = loginPresenter = (LoginPresenter) presenter;    }}

Presenter-LoginPresenter–负责acvity的业务处理

package rxjava.application.com.androidmyp.Presenter;import java.util.HashMap;import java.util.List;import rx.Observable;import rx.Subscriber;import rx.Subscription;import rx.functions.Func1;import rx.subscriptions.CompositeSubscription;import rxjava.application.com.androidmyp.Beans.BaseBean;import rxjava.application.com.androidmyp.Beans.SchoolClass;import rxjava.application.com.androidmyp.Data.ApiException;import rxjava.application.com.androidmyp.Data.ApiInterceptor;import rxjava.application.com.androidmyp.Data.ApiManger;import rxjava.application.com.androidmyp.Data.RxSchedulers;import rxjava.application.com.androidmyp.Login.UserLoginContract;/** * Created by Administrator on 2016/4/13. */public class LoginPresenter implements BasePresenter{    private UserLoginContract mView;//当前的页面    private CompositeSubscription msubscription;//管理所有的订阅    public LoginPresenter(UserLoginContract mView) {        this.mView = mView;        this.mView.setPresenter(this);        this.msubscription = new CompositeSubscription();    }    /**     * 获取class     */    public void getClassInfo() {        HashMap<String, String> map = new HashMap<>();        map.put("id", "3");        Subscription i  = ApiManger.getIntance().api.getClass(map)                .flatMap(new Func1<BaseBean<List<SchoolClass>>, Observable<List<SchoolClass>>>() {                    @Override                    public Observable<List<SchoolClass>> call(BaseBean<List<SchoolClass>> listBaseBean) {                        return new ApiInterceptor().flatResult(listBaseBean);                    }                })                .compose(RxSchedulers.<List<SchoolClass>>IO_Main())                .subscribe(new Subscriber<List<SchoolClass>>() {                    @Override                    public void onCompleted() {                        //获取数据完成                        mView.loginSuccess();                    }                    @Override                    public void onError(Throwable e) {                       ApiException apiException = (ApiException) e;                        mView.showToast(apiException.getRespMSg());                    }                    @Override                    public void onNext(List<SchoolClass> schoolClasses) {                        //得到数据,在页面可以进行数据绑定操作                    }                });        this.msubscription.add(i);//把订阅加入管理集合中    }    @Override    public void onDestroy() {        //在activity结束生命周期的时候取消订阅,解除对context的引用        if(msubscription != null){            this.msubscription.unsubscribe();        }    }}

详细的代码:源码下载

总结:android mvp是一个很好的架构,我们可以利用他很好的解耦Acitivity,我们不能让他成为我们的累赘!

0 0
原创粉丝点击