Android MVP 的理解

  • 在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值