1. 程式人生 > >mvp框架學習實戰程式碼(配合retrofit+dagger2+rxjava)

mvp框架學習實戰程式碼(配合retrofit+dagger2+rxjava)

【轉載請標明出處http://blog.csdn.net/sw5131899/article/details/51860922,謝謝】

最近一直在學習框架的搭建和使用,對於mvp,很多開發者有自己的獨特見解,褒貶不一。不過我還是覺得它有學習的必要。在某些大專案上,使用mvp可以方便後期的程式碼維護和更新。廢話不多說,開始進入正題。
首先是瞭解這些技術,我推薦幾個個人覺得比較好的文件。
rxjava:http://blog.csdn.net/sw5131899/article/details/52064431
dagger2:http://blog.csdn.net/sw5131899/article/details/51839172
retrofit:http://blog.csdn.net/u014165119/article/details/49280779
這些都是基礎的知識,那麼開始框架的搭建。
首先,匯入gradle。為了避免麻煩,我直接把gradle整個文件的內容粘出來。
</pre><pre name="code" class="java">apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.abings.daager2demo"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lintOptions {
        warning 'InvalidPackage'
    }
}
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-alpha1'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    apt 'com.google.dagger:dagger-compiler:2.2'
    provided 'org.glassfish:javax.annotation:10.0-b28'
    compile 'com.google.dagger:dagger:2.2'
    compile 'com.jakewharton:butterknife:7.0.1'
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
    compile 'com.squareup.retrofit2:converter-gson:2.+'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile "com.squareup.retrofit:adapter-rxjava:2.0.0-beta2"
    compile "com.squareup.okhttp:okhttp:2.7.0"
}
配置dagger2,建立module和componnet。

建立appModule

@Module
public class AppModule {
    private Application application;

    public AppModule(Application application){
        this.application = application;
    }

    @Singleton
    @Provides
    public Application providesApplication(){
        return application;
    }

    @Provides
    @Singleton
    APIService provideAPIService() {
        return RetrofitUtils.createApi(RxJavaCallAdapterFactory.create());
    }
}
appModule提供application的例項和APIService的例項,要保證它們是全域性的即單例。加上@Singleton確定作用範圍。

建立applicationComponent

@Singleton
@Component(modules = AppModule.class)
public interface ApplicationComponent {
    ActivityComponent plus(ActivityModule activityModule);
    DataManager dataManager();
}
Componnet相當於一個橋樑,將ActivityComponent作為其子Component。

建立PerActivity的scope

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}

@Scope and @Singleton
這個註解是用來劃分作用域的,標記當前物件使用範圍。
比如限制物件只能在所有Activity中使用,或者只能在Application中使用,或者只能在Fragment中使用

@Singleton 單例模式全域性共用一個物件 就是@Scope的一個實現

同理

@PerActivity
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {
    void inject(LoginActivity loginActivity);
    void inject(AActivity aActivity);
}
@Module
public class ActivityModule {
    private Activity mActivity;

    public ActivityModule(Activity activity){
        mActivity = activity;
    }

    @PerActivity
    @Provides
    public Activity providesActivity(){
        return mActivity;
    }
}
現在需要一個App全域性類,提供ActivityComponent物件。
public class App extends Application {
    private static ApplicationComponent applicationComponent;
    private ActivityComponent activityComponent;

    @Inject
    DataManager mDataManager;
    public static App get(Context context){
        return (App) context.getApplicationContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        applicationComponent = DaggerApplicationComponent.builder().appModule(new AppModule(this)).build();
    }

    public void createActivityComponent(Activity activity){
        activityComponent = applicationComponent.plus(new ActivityModule(activity));
    }


    public ActivityComponent getActivityComponent(){
        return activityComponent;
    }

    public void releaseActivityComponent(){
        activityComponent = null;
    }


}
dagger所需的配置差不多完成了。接下來就是rxjava和retrofit的配置使用了。
public interface APIService {
    @GET("list/{page}")
    Observable<JSONObject> getDatas(@Path("page")int page);
}
public class RetrofitUtils {

    public static final String BASE_URL = "http://v3.wufazhuce.com:8000/api/movie/";
    public static Retrofit singleton;
    public static <T> T createApi(Class<T> clazz, Interceptor interceptor, RxJavaCallAdapterFactory factory) {
        //if (singleton == null) {
        synchronized (RetrofitUtils.class) {
            if (singleton == null) {
                Retrofit.Builder builder = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                                //.addConverterFactory(FastJsonConverterFactory.create())
                        .addConverterFactory(JsonConverterFactory.create());
                // .addConverterFactory(FastJsonConvertFactory.create());
                if (interceptor != null) {
                    builder.client(createInterceptor(interceptor));
                }
                if (factory != null) {
                    builder.addCallAdapterFactory(factory);
                }
                singleton = builder.build();
            }
        }
        return singleton.create(clazz);
    }


    public static <T> APIService createApi(RxJavaCallAdapterFactory factory) {
        return createApi(APIService.class, null, factory);
    }

    private static OkHttpClient createInterceptor(Interceptor interceptor) {
        OkHttpClient client = new OkHttpClient();
        client.networkInterceptors().add(interceptor);
        return client;
    }
}
這裡想要將retrofit的例項通過dagger提供給下層使用,不用每次都建立retrofit物件。

接下來搭建mvp框架。

public abstract class BaseActivity extends AppCompatActivity{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(setlayoutId());
        App.get(this).createActivityComponent(this);
        inject();
        initEvents(savedInstanceState);
    }

    protected abstract int setlayoutId();
    protected abstract void inject();
    protected abstract void initEvents(Bundle savedInstanceState);

}
public interface IBaseView<T> {
    void showMessage(String mes);
}
public interface Precenter<T extends IBaseView> {
    void attachView(T mvpView);
    void detachView();
}
具體使用mvp
public class LoginActivity extends BaseActivity implements LoginMvpView {


    @Inject
    LoginPecenter loginPecenter;


    @Bind(R.id.listview)
    ListView listView;

    @Override
    protected int setlayoutId() {
        return R.layout.activity_login;
    }

    @Override
    protected void inject() {
        App.get(this).getActivityComponent().inject(this);
        loginPecenter.attachView(this);
    }

    @Override
    protected void initEvents(Bundle savedInstanceState) {
        ButterKnife.bind(this);
    }


    @Override
    public void showMessage(String mes) {
        Toast.makeText(LoginActivity.this, mes, Toast.LENGTH_SHORT).show();
    }

    @OnClick(R.id.button)
    public void toA(){
//        startActivity(new Intent(this, AActivity.class));
        loginPecenter.loadData(0);
    }


    @Override
    public void showData(List list) {

    }
}
public interface LoginMvpView extends IBaseView {
    void showData(List list);
}
public class LoginPecenter implements Precenter<LoginMvpView> {

    private LoginMvpView mvpView;
    private final DataManager dataManager;
    private Subscription subscription;

    @Inject
    public LoginPecenter(DataManager dataManager){
        this.dataManager = dataManager;
    }

    @Override
    public void attachView(LoginMvpView mvpView) {
        this.mvpView = mvpView;
    }

    @Override
    public void detachView() {
        mvpView = null;
        if (subscription != null){
            subscription.unsubscribe();
        }
    }

    public void loadData(int page){
        subscription = dataManager.getdatas(page).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<JSONObject>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(JSONObject result) {
                Log.i("TAG00",result.toString());
                Gson gson = new Gson();
                listBean listBean = gson.fromJson(result.toString(), listBean.class);
                //省略更新UI邏輯。。
            }
        });

    }

}
在提供APIService例項的時候,需要一個類作為中轉。API是介面,不能提供例項。所以建立一個Datamanager
@Singleton
public class DataManager {
    private final APIService apiService;

    @Inject
    public DataManager(APIService apiService){
        this.apiService = apiService;
    }

    public Observable<JSONObject> getdatas(int page) {
        return apiService.getDatas(page);
    }
}
重點的類也就這些了,其實我也不能為大家講解清楚,只能意會不能言傳,大家多看看原始碼,有利於學習提高。大家一起加油。

框架在開發中有著不可取代的地位,所以值得我們下功夫去學習。


附上git原始碼: