安卓轻量级MVP

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.shao.mvp">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:name=".app.App"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".view.LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name=".view.MainActivity">
        </activity>
    </application>

</manifest>

style.xml

//为了显示的效果美观
//先把style.xml的AppTheme的parent修改为
Theme.AppCompat.DayNight.NoActionBar

MVP.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'me.tatarka:gradle-retrolambda:3.2.5'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

app.gradle

apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example.shao.mvp"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    dataBinding {
        enabled true
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    //RxJava2
    compile 'io.reactivex.rxjava2:rxjava:2.0.7'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

    //retrofit2
    compile 'com.squareup.retrofit2:retrofit:2.2.0'

    //Retrofit2 和 RxJava 集成
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'

    //retrofit2 Gson转换器
    compile 'com.squareup.retrofit2:converter-gson:2.2.0'

    //okHttp3
    compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'

    //自定义SnackBar
    compile 'com.trycatch.android:mysnackbar:1.2.2'
}

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fitsSystemWindows="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <EditText
            android:id="@+id/et_login_name"
            android:hint="账号"
            android:layout_marginTop="100dp"
            android:layout_gravity="center"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>

        <EditText
            android:id="@+id/et_password"
            android:hint="密码"
            android:layout_marginTop="50dp"
            android:layout_gravity="center"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>

        <Button
            android:id="@+id/bt_login"
            android:text="登录"
            android:layout_marginTop="50dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</layout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fitsSystemWindows="true">

    <data>
        <variable
            name="userDto"
            type="com.example.shao.mvp.model.dto.UserDto"/>
    </data>

    <LinearLayout
        android:layout_margin="60dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:text="用户ID"
                android:textSize="17sp"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>

            <TextView
                android:text="@{String.valueOf(userDto.userId)}"
                android:textSize="17sp"
                android:layout_weight="2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>

        </LinearLayout>

        <LinearLayout
            android:layout_marginTop="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:text="用户名"
                android:textSize="17sp"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>

            <TextView
                android:text="@{userDto.userName}"
                android:textSize="17sp"
                android:layout_weight="2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>

        </LinearLayout>

        <LinearLayout
            android:layout_marginTop="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:text="登录时间"
                android:textSize="17sp"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>

            <TextView
                android:text="@{userDto.userLoginTime}"
                android:textSize="17sp"
                android:layout_weight="2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>

        </LinearLayout>

    </LinearLayout>

</layout>
建立对应目录

先建立工具类util

ActivityUtil

package com.example.shao.mvp.util;

import android.app.Activity;
import android.util.Log;

import java.util.Stack;

public class ActivityUtil {
    private static Stack<Activity> mActivityStack;
    private static volatile ActivityUtil mScreenManager;

    private ActivityUtil() {
    }

    /**
     * Activity栈单例
     */
    public static ActivityUtil getInstance() {
        if (mScreenManager == null) {
            synchronized (ActivityUtil.class) {
                if (mScreenManager == null) {
                    mScreenManager = new ActivityUtil();
                }
            }
        }
        return mScreenManager;
    }

    /**
     * 移除栈顶activity
     */
    public void popActivity(Activity activity) {
        if (activity != null) {
            activity.finish();
            mActivityStack.remove(activity);
            Log.d("ActivityUtil pop: ", activity.getLocalClassName());
        }
    }

    public Activity currentActivity() {
        return mActivityStack.lastElement();
    }

    /**
     * 将activity入栈
     */
    public void pushActivity(Activity activity) {
        if (mActivityStack == null) {
            mActivityStack = new Stack<>();
        }
        mActivityStack.add(activity);
        Log.d("ActivityUtil push: ", activity.getLocalClassName());
    }

    /**
     * 移除栈顶到class之间的activity
     */
    public void popAllActivityExceptOne(Class clazz) {
        while (true) {
            if (mActivityStack.empty()) {
                break;
            } else {
                Activity activity = mActivityStack.peek();
                if (activity == null) {
                    break;
                }
                if (activity.getClass().equals(clazz)) {
                    break;
                }
                popActivity(activity);
                Log.d("ActivityUtil pop: ", activity.getLocalClassName());
            }
        }

    }

    /**
     * 打印栈内所有Activity名
     */
    public void logAllActivity() {
        for (Activity mActivity : mActivityStack) {
            Log.d("ActivityUtil print: ", mActivity.getLocalClassName());
        }
    }

    /**
     * 所有Activity出栈
     */
    public void popAllActivity() {
        while (true) {
            if (mActivityStack.empty()) {
                break;
            } else {
                Activity activity = mActivityStack.peek();
                if (activity == null) {
                    break;
                }
                popActivity(activity);
                Log.d("ActivityUtil pop: ", activity.getLocalClassName());
            }
        }
    }
}

DeviceUtil

package com.example.shao.mvp.util;

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.TypedValue;

public class DeviceUtil {
    /**
     * 获取当前设备状态栏高度
     */
    public static int getStatusBarHeight(Context context) {
        int result = dp2px(context, 25);
        int resourceId = context.getResources()
                .getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 获取屏幕宽度
     */
    public static int getScreenWidth(Context mContext) {
        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
        return dm.widthPixels;
    }

    /**
     * 获取屏幕尺高度
     */
    public static int getScreenHeight(Context mContext) {
        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
        return dm.heightPixels;
    }

    public static int dp2px(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
                context.getResources().getDisplayMetrics());
    }
    
    public static int sp2px(Context context, float spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,
                context.getResources().getDisplayMetrics());
    }

    public static float px2dp(Context context, float pxVal) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (pxVal / scale);
    }
    
    public static float px2sp(Context context, float pxVal) {
        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
    }
}

NetworkUtil

package com.example.shao.mvp.util;

import android.content.Context;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;

import java.util.List;

public class NetworkUtil {
    /**
     * 网络是否可用
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivity =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Gps是否打开
     */
    public static boolean isGpsEnabled(Context context) {
        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        List<String> accessibleProviders = locationManager.getProviders(true);
        return accessibleProviders != null && accessibleProviders.size() > 0;
    }

    /**
     * wifi是否打开
     */
    public static boolean isWifiEnabled(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context
                .CONNECTIVITY_SERVICE);
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context
                .TELEPHONY_SERVICE);
        return ((connectivityManager.getActiveNetworkInfo() != null
                && connectivityManager.getActiveNetworkInfo().getState() == NetworkInfo.State.CONNECTED)
                || telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS);
    }

    /**
     * 判断当前网络是否是wifi网络
     */
    public static boolean isWifi(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService
                (Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
            return true;
        }
        return false;
    }

    /**
     * 判断当前网络是否是GPRS网络
     */
    public static boolean isGPRS(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService
                (Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
            return true;
        }
        return false;
    }
}

SnackBarUtil

package com.example.shao.mvp.util

import android.view.View;
import com.example.shao.mvp.R;
import com.trycatch.mysnackbar.Prompt;
import com.trycatch.mysnackbar.TSnackbar;

public class SnackBarUtil {
    public static void showShort(View view, String msg) {
        TSnackbar.make(view, msg, TSnackbar.LENGTH_SHORT, TSnackbar.APPEAR_FROM_TOP_TO_DOWN)
                .setPromptThemBackground(Prompt.SUCCESS)
                .addIcon(R.mipmap.XXX).show();
    }
}

RxUtil

package com.example.shao.mvp.util;

import com.example.shao.mvp.model.MyHttpResponse;
import io.reactivex.Observable;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class RxUtil {
    /**
     * 统一线程处理
     */
    public static <T> ObservableTransformer<T, T> rxSchedulerHelper() {
        return upstream -> upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 统一返回结果处理 自行处理异常
     */
    public static <T> ObservableTransformer<MyHttpResponse<T>, T> handleMayErrorResult() {
        return upstream -> upstream.flatMap(tHttpResponse -> {
            if (tHttpResponse.getSuccess() == true) {
                return createData(tHttpResponse.getJsonData());
            } else {
                return createErrorData(new Throwable());
            }
        });
    }

    /**
     * 生成Observable
     */
    public static <T> Observable<T> createData(final T t) {
        return Observable.create(e -> {
            e.onNext(t);
            e.onComplete();
        });
    }

    /**
     * 生成Error Observable
     */
    public static <T> Observable<T> createErrorData(Throwable throwable) {
        return Observable.create(e -> {
            e.onError(throwable);
        });
    }
}

SimpleSubscriber

package com.example.shao.mvp.widget;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

public abstract class SimpleSubscriber<T> implements Observer<T> {

    private Disposable disposable;

    protected SimpleSubscriber() {
    }

    @Override
    public void onSubscribe(Disposable d) {
        disposable = d;
    }

    @Override
    public void onComplete() {
    }

    private boolean isDataError() {
        return false;
    }
}

全局App和基类

App

package com.example.shao.mvp.app;

import android.app.Application;
import android.content.Context;
import com.example.shao.mvp.util.DeviceUtil;

public class App extends Application {

    private static App applicationInstance;
    public static int screenWidth = 0;
    public static int screenHeight = 0;
    public Context mContext;

    public static App getInstance() {
        return applicationInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        applicationInstance = this;
        mContext = getApplicationContext();
        screenWidth = DeviceUtil.getScreenWidth(mContext);
        screenHeight = DeviceUtil.getScreenHeight(mContext);
        if (screenWidth > screenHeight) {
            int t = screenHeight;
            screenHeight = screenWidth;
            screenWidth = t;
        }
    }
}

BaseActivity

package com.example.shao.mvp.base;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import android.view.WindowManager;
import com.example.shao.mvp.util.ActivityUtil;
import com.example.shao.mvp.util.SnackBarUtil;

public abstract class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityUtil.getInstance().pushActivity(this);      //Activity入栈
        setPresenter();                                     //设置对应Presenter
        setBinding();                                       //设置数据绑定
        initEventAndData();                                 //初始化事件和数据

        //判断当前设备版本号是否为4.4以上,如果是,则通过调用setTranslucentStatus让状态栏变透明
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setTranslucentStatus(true);
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityUtil.getInstance().popActivity(this);       //Activity出栈
    }

    @TargetApi(19)
    private void setTranslucentStatus(boolean on) {
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }

    protected abstract void setPresenter();

    protected abstract void setBinding();

    protected abstract void initEventAndData();

    protected void hint(String msg) {
        SnackbarUtil.showShort(getWindow().getDecorView(), msg);
    }
}

UserDto

package com.example.shao.mvp.model.dto;

import java.io.Serializable;

public class UserDto implements Serializable {

    private Integer userId;
    private String userName;
    private String userLoginTime;

    public UserDto() {
    }

    public UserDto(Integer userId, String userName, String userLoginTime) {
        this.userId = userId;
        this.userName = userName;
        this.userLoginTime = userLoginTime;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserLoginTime() {
        return userLoginTime;
    }

    public void setUserLoginTime(String userLoginTime) {
        this.userLoginTime = userLoginTime;
    }
}

ApiSetting

package com.example.shao.mvp.model;

import com.example.shao.mvp.app.App;
import java.io.File;


public class ApiSetting {

    public static final String APP_URL = "http://192.168.0.3:8080/";

    public static final String PATH_DATA = App.getInstance()
            .getCacheDir()
            .getAbsolutePath() + File.separator + "data";

    public static final String PATH_CACHE = PATH_DATA + "/NetCache";
}

MyHttpResponse

package com.example.shao.mvp.model;

public class MyHttpResponse<T> {

    private boolean isSuccess;
    private T jsonData;

    public boolean getSuccess() {
        return isSuccess;
    }

    public void setSuccess(boolean success) {
        isSuccess = success;
    }

    public T getJsonData() {
        return jsonData;
    }

    public void setJsonData(T jsonData) {
        this.jsonData = jsonData;
    }

}

网络请求封装

OkHttpManager

package com.example.shao.mvp.model;

import com.example.shao.mvp.BuildConfig;
import com.example.shao.mvp.app.App;
import com.example.shao.mvp.util.NetworkUtil;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class OkHttpManager {

    private static volatile OkHttpClient mOkHttpClient;

    public static OkHttpClient getInstance() {
        if (mOkHttpClient == null) {
            synchronized (RetrofitManager.class) {                              //同步
                if (mOkHttpClient == null) {                                    //双重检查
                    OkHttpClient.Builder builder = new OkHttpClient.Builder();
                    mOkHttpClient = provideClient(builder);
                }
            }
        }
        return mOkHttpClient;
    }

    private static OkHttpClient provideClient(OkHttpClient.Builder builder) {
        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
            builder.addInterceptor(loggingInterceptor);
        }
        //File cacheFile = new File();
        //Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
        Interceptor cacheInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (!NetworkUtil.isNetworkAvailable(App.getInstance()
                        .getApplicationContext())) {
                    request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
                }
                Response response = chain.proceed(request);
                if (NetworkUtil.isNetworkAvailable(App.getInstance()
                        .getApplicationContext())) {
                    int maxAge = 0;
                    // 有网络时, 不缓存, 最大保存时长为0
                    response.newBuilder()
                            .header("Cache-Control", "public, max-age=" + maxAge)
                            .removeHeader("Pragma")
                            .build();
                } else {
                    // 无网络时,设置超时为4周
                    int maxStale = 60 * 60 * 24 * 28;
                    response.newBuilder()
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            .removeHeader("Pragma")
                            .build();
                }
                return response;
            }
        };
        //        Interceptor apikey = new Interceptor() {
        //            @Override
        //            public Response intercept(Chain chain) throws IOException {
        //                Request request = chain.request();
        //                request = request.newBuilder()
        //                        .addHeader("apikey",Constants.KEY_API)
        //                        .build();
        //                return chain.proceed(request);
        //            }
        //        }
        //        设置统一的请求头部参数
        //        builder.addInterceptor(apikey);
        //设置缓存
        builder.addNetworkInterceptor(cacheInterceptor);
        builder.addInterceptor(cacheInterceptor);
        //builder.cache(cache);
        //设置超时
        builder.connectTimeout(10, TimeUnit.SECONDS);
        builder.readTimeout(20, TimeUnit.SECONDS);
        builder.writeTimeout(20, TimeUnit.SECONDS);
        //错误重连
        builder.retryOnConnectionFailure(true);
        return builder.build();
    }
}

RetrofitManager

package com.example.shao.mvp.model;

import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitManager {

    private static volatile Retrofit.Builder mRetrofitBuilder;

    public static Retrofit.Builder getInstance() {
        synchronized (RetrofitManager.class) {                          //同步
            if (mRetrofitBuilder == null) {                             //双重检查
                mRetrofitBuilder = new Retrofit.Builder()
                        .client(OkHttpManager.getInstance())
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create());
            }
        }
        return mRetrofitBuilder;
    }
}

LoginService

package com.example.shao.mvp.model.service;

import com.example.shao.mvp.model.dto.UserDto;
import com.example.shao.mvp.model.MyHttpResponse;
import io.reactivex.Observable;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;

import java.util.Map;

public interface LoginService {

    @POST("rds_user/loginCheck")
    Observable<MyHttpResponse<UserDto>> loginCheck(@QueryMap Map<String, String> map);
}

LoginManager

package com.example.shao.mvp.model.manager;

import com.example.shao.mvp.model.dto.UserDto;
import com.example.shao.mvp.model.ApiSetting;
import com.example.shao.mvp.model.MyHttpResponse;
import com.example.shao.mvp.model.RetrofitManager;
import com.example.shao.mvp.model.service.LoginService;
import io.reactivex.Observable;

import java.util.Map;


public class LoginManager {

    private static LoginService loginService = RetrofitManager.getInstance()
            .baseUrl(ApiSetting.APP_URL)
            .build()
            .create(LoginService.class);

    public static Observable<MyHttpResponse<UserDto>> loginCheck(Map<String, String> map) {
        return loginService.loginCheck(map);
    }

}

LoginContract(MainContract同理)

package com.example.shao.mvp.presenter.contract;


import com.example.shao.mvp.model.dto.UserDto;

public interface LoginContract {

    interface View {
        void sendUserInfo(UserDto userDto);
    }

    interface Presenter {
        void loginCheck(String loginName,
                        String password);
    }

}

LoginPresenter(MainPresenter同理)

package com.example.shao.mvp.presenter;

import com.example.shao.mvp.model.dto.UserDto;
import com.example.shao.mvp.model.manager.LoginManager;
import com.example.shao.mvp.presenter.contract.LoginContract;
import com.example.shao.mvp.util.RxUtil;
import com.example.shao.mvp.widget.SimpleSubscriber;

import java.util.HashMap;
import java.util.Map;


public class LoginPresenter implements LoginContract.Presenter {

    private LoginContract.View mView;

    public LoginPresenter(LoginContract.View mView) {
        this.mView = mView;
    }

    @Override
    public void loginCheck(String loginName, String password) {
        Map<String, String> map = new HashMap<>();
        map.put("loginName", loginName);
        map.put("passWord", password);
        LoginManager.loginCheck(map)
                .compose(RxUtil.rxSchedulerHelper())
                .compose(RxUtil.handleMayErrorResult())
                .subscribe(new SimpleSubscriber<UserDto>() {
                    @Override
                    public void onNext(UserDto userDto) {
                        mView.sendUserInfo(userDto);
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }
                });
    }

}

LoginActivity

package com.example.shao.mvp.view;

import android.databinding.DataBindingUtil;
import android.view.View;
import com.example.shao.mvp.R;
import com.example.shao.mvp.base.BaseActivity;
import com.example.shao.mvp.databinding.ActivityLoginBinding;
import com.example.shao.mvp.model.dto.UserDto;
import com.example.shao.mvp.presenter.LoginPresenter;
import com.example.shao.mvp.presenter.contract.LoginContract;


public class LoginActivity extends BaseActivity implements LoginContract.View, View.OnClickListener {

    private LoginPresenter mPresenter;
    private ActivityLoginBinding mBinding;

    @Override
    protected void setPresenter() {
        mPresenter = new LoginPresenter(this);
    }

    @Override
    protected void setBinding() {
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_login);
    }

    @Override
    protected void initEventAndData() {
        mBinding.btLogin.setOnClickListener(this);
    }

    @Override
    public void sendUserInfo(UserDto userDto) {
        MainActivity.actionStart(this, userDto);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_login:
                mPresenter.loginCheck(mBinding.etLoginName.getText().toString(),
                        mBinding.etPassword.getText().toString());
                break;
        }
    }
}

MainActivity

package com.example.shao.mvp.view;

import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import com.example.shao.mvp.R;
import com.example.shao.mvp.base.BaseActivity;
import com.example.shao.mvp.databinding.ActivityMainBinding;
import com.example.shao.mvp.model.dto.UserDto;
import com.example.shao.mvp.presenter.MainPresenter;
import com.example.shao.mvp.presenter.contract.MainContract;


public class MainActivity extends BaseActivity implements MainContract.View {

    private MainPresenter mPresenter;
    private ActivityMainBinding mBinding;

    public static void actionStart(Context context, UserDto userDto) {
        Intent intent = new Intent(context, MainActivity.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable("userDto", userDto);
        intent.putExtras(bundle);
        context.startActivity(intent);
    }

    @Override
    protected void setPresenter() {
        mPresenter = new MainPresenter(this);
    }

    @Override
    protected void setBinding() {
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    }

    @Override
    protected void initEventAndData() {
        Intent intent = getIntent();
        UserDto userDto = (UserDto) intent.getSerializableExtra("userDto");
        mBinding.setUserDto(userDto);
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容