如何使用MVP+Dagger2+RxJava+Retrofit開發(1)


概述

  • 在2016年5,6月份開始在知乎上看到開發方法,那時候記得是看mvc,mvp,mvvm這三種開發模式區別,后面進一步了解到google在github上開源了使用這3種模式進行Android開發的demo.不同的項目有不同的情況,開發項目是找一個最適合的,而不是性能最好,開發時間最短等。

  • MVP是一種開發模式或者架構,RxJava與Retrofit是兩個庫,前面的是異步的庫,后面的是提供Restful請求的庫,這兩個庫都是為了MVP開發模式服務的。當然,他的適用場景是業務邏輯復雜的項目,也就是解決控制層耦合性太高。

  • Dagger2庫,RxJava庫,Retrofit庫會進行簡單介紹,了解其運作的機制。

Dagger2庫

關鍵概念

  • Inject--你用它告訴Dagger這個類或者字段需要依賴注入

  • Module-- Modules類里面的方法專門提供依賴,所以我們定義一個類,用@Module注解,這樣Dagger在構造類的實例的時候,就知道從哪里去找到需要的依賴

  • Provide--在modules中,我們定義的方法是用這個注解,以此來告訴Dagger我們想要構造對象並提供這些依賴。

  • Component--Components從根本上來說就是一個注入器,也可以說是@Inject和@Module的橋梁,它的主要作用就是連接這兩個部分。 Components可以提供所有定義了的類型的實例,比如:我們必須用@Component注解一個接口然后列出所有的@Modules組成該組件,如 果缺失了任何一塊都會在編譯的時候報錯。所有的組件都可以通過它的modules知道依賴的范圍。

  • Scope-- Scopes可是非常的有用,Dagger2可以通過自定義注解限定注解作用域。后面會演示一個例子,這是一個非常強大的特點,因為就如前面說的一樣,沒 必要讓每個對象都去了解如何管理他們的實例。在scope的例子中,我們用自定義的@PerActivity注解一個類,所以這個對象存活時間就和 activity的一樣。簡單來說就是我們可以定義所有范圍的粒度(@PerFragment, @PerUser, 等等)。

  • Qualifier--當類的類型不足以鑒別一個依賴的時候,我們就可以使用這個注解標示。例如:在Android中,我們會需要不同類型的context,所以我們就可以定義 qualifier注解“@ForApplication”和“@ForActivity”,這樣當注入一個context的時候,我們就可以告訴 Dagger我們想要哪種類型的context。

如何在MVP中使用

創建BasePresenter與BaseView

  • MVP架構中M與V通過P進行交互,activity用來顯示不再負責具體業務邏輯,職責明確,便於測試;

  • BasePresenter與BaseView抽象出視圖中公共的行為,可以在activity或者fragment中實現BaseView的子類,渲染界面;

public interface BasePresenter {

    //訂閱
    void subscribe();

    //解訂
    void unsubscribe();
}

public interface BaseView<T> {

    void  setPresenter(T presenter);//view中設置處理器

}

創建處理器(MVP中的P)

1.新建MineContract,view與presenter的抽象接口集合,相當於講下要去做那些事情

public interface MineContract {

    interface View extends BaseView<Presenter>{

        void login_success(String response);

        void login_failure(String msg);

        void network_exception(int errcode);

        void network_normal();

    }

    interface Presenter extends  BasePresenter{

        void login(User user);

    }

2.新建MinePresenter,實現MineContract.Presenter接口方法,相當於事情具體怎么去做

public class MinePresenter implements MineContract.Presenter {

    private final static String TAG="MinePresenter";

    private MineContract.View mView;

    
    public MinePresenter(MineContract.View view) {
        this.mView = view;
        this.mView.setPresenter(this);
    }

    @Override
    public void subscribe() {

    }

    @Override
    public void unsubscribe() {

    }

    @Override
    public void login(User user) {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mView.login_success("success");
                Log.d(TAG,"logined");
            }
        },500);

    }
}

創建實體(MVP中的M)

創建User類,作為登錄測試

public class User {

    private String uId;

    private  String uName;

    private String uPwd;

    private String uType;

    private String uLevel;

   //省略set與get方法
}

創建界面(MVP中的V)

  • 創建MainActivity,采用嵌套fragment方式,繼承自FragmentActivity
public class MainActivity extends FragmentActivity  {

    private FragmentManager mFragMgr;

    @Inject
     MinePresenter presenter;

    private MineFragment mineFragment;

    private final String MINE = "Mine";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFragMgr = getSupportFragmentManager();
        initFragments();
        showFragments(MINE,true);
    }

 private void initFragments() {
        mineFragment = new MineFragment();
    }

    private void showFragments(String tag, boolean init) {
        FragmentTransaction trans = mFragMgr.beginTransaction();
        if (init) {
            trans.add(R.id.main_content, getFragmentByTag(tag), tag);
            trans.addToBackStack(tag);
        } else {
            trans.replace(R.id.main_content, getFragmentByTag(tag), tag);
        }
        trans.commit();
    }

    private Fragment getFragmentByTag(String tag) {
        if (MINE.equals(tag)) {
            return mineFragment;
        }
        return null;
    }


}
  • 創建MineFragment,需要實現implements MineContract.View接口
public class MineFragment extends Fragment implements MineContract.View {
    //省略部分代碼  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        uName = (LikeEditText) view.findViewById(R.id.uName);
        uPwd = (LikeEditText) view.findViewById(R.id.uPwd);
        loginBtn = (Button) view.findViewById(R.id.login_btn);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                User user=new User();
                user.setuName(uName.getText().toString());
                user.setuPwd(uPwd.getText().toString());
                minePresenter.login(user);
            }
        });
    }

前面講的都是mvp架構基本搭建,下面是如何運用dagger2;

創建提供應用實例的AppComponent

一個應用在創建時會產生唯一的Application對象,可以在應用的onCreate函數創建,下面有幾個步驟:

1.創建提供應用對象的Component

1.1創建提供應用對象的Module

@Module
public class AppModule {

    private  Context mContext;

    public AppModule(Context context){
        this.mContext=context;
    }

    @Provides
    public Context provideContext(){
        return this.mContext;
    }


}

1.2創建AppComponent為其他Component提供依賴

@Component(modules = AppModule.class)
public interface AppComponent {
 Context getContext();
}
2.構建AppComponent的實例
public class SampleApplication extends Application {

    private AppComponent appComponent;

    private static SampleApplication mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance=this;
        appComponent=DaggerAppComponent.builder().appModule(new AppModule(this)).build();
    }

    public static SampleApplication  getInstance(){
        return mInstance;
    }

    public AppComponent getAppComponent(){
        return  appComponent;
    }

}

在MainActivity如何自動注入MinePresenter

  • 1.修改MinePresenter代碼-構造方法注入
  @Inject
    public MinePresenter(MineContract.View view) {
        this.mView = view;
        this.mView.setPresenter(this);
    }
  • 2.創建MinePresenterModule-提供MineContract.View實例
@Module
public class MinePresenterModule {

    private final MineContract.View mView;

    public MinePresenterModule(MineContract.View view) {
        mView = view;
    }

    @Provides
    MineContract.View provideStatisticsContractView() {
        return mView;
    }
}
  • 3.修改MainComponent
@Component(dependencies = AppComponent.class,modules = MinePresenterModule.class)
public interface MainComponent {
    MineFragment inject(MineFragment mineFragment);

    MainActivity inject(MainActivity mainActivity);
}
  • 4.修改MainActivity代碼-成員變量注入與注入MineFragment
 @Inject
  MinePresenter presenter;

 private void initFragments() {
        mineFragment = new MineFragment();
         DaggerMainComponent.builder().minePresenterModule(new MinePresenterModule(mineFragment)).appComponent(SampleApplication.getInstance().getAppComponent()).build().inject(this);

    }

以上所有的步驟已完成,編譯項目,dagger2自動生成相關類,並完成注入。

總結

  • 創建module,一般應用於第三方包對象或者應用對象
  • 創建Component,依賴注入器,復雜把注入對象注入到注解成員變量

構造方法注入:在類的構造方法前面注釋@Inject
成員變量注入:在類的成員變量(非私有)前面注釋@Inject


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM