Android -- 帶你一點點封裝項目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)

1,這一篇博客是和你們一塊兒來封裝咱們最後的Dagger2,其實以前也寫過關於簡單的Dagger2,這裏是地址,徹底沒了解的同窗能夠先去看一下這篇,感謝不少小夥伴一直在耐心的等待這一篇html

2,Dagger2能夠說是些技術中最難上手的,不過把主要的四個註解理解到位了,基本上就能夠用了:java

@Inject Inject主要有兩個做用,一個是使用在構造函數上,經過標記構造函數讓Dagger2來使用(Dagger2經過Inject標記能夠在須要這個類實例的時候來找到這個構造函數並把相關實例new出來)從而提供依賴,另外一個做用就是標記在須要依賴的變量讓Dagger2爲其提供依賴。

@Provide 用Provide來標註一個方法,該方法能夠在須要提供依賴時被調用,從而把預先提供好的對象當作依賴給標註了@Injection的變量賦值。provide主要用於標註Module裏的方法

@Module 用Module標註的類是專門用來提供依賴的。有的人可能有些疑惑,看了上面的@Inject,須要在構造函數上標記才能提供依賴,那麼若是咱們須要提供的類構造函數沒法修改怎麼辦,好比一些jar包裏的類,咱們沒法修改源碼。這時候就須要使用Module了。Module能夠給不能修改源碼的類提供依賴,固然,能用Inject標註的經過Module也能夠提供依賴

@Component Component通常用來標註接口,被標註了Component的接口在編譯時會產生相應的類的實例來做爲提供依賴方和須要依賴方之間的橋樑,把相關依賴注入到其中。

  下面你這張圖片很相像的歸納了上面四個標籤的做用android

        

   還有兩個常見的標籤是@Scope和@Qulifier ,@Scope標籤你能夠將它理解成單例標記,@Qulifier能夠簡單的理解成區分須要的對象有兩個或者兩個以上構造方法(主要用於區分),git

     首先咱們用一個簡單的場景來引入吧,如今咱們項目使用MVP架構, 而引入Dagger2的主要目的是解決咱們在Activity中new Presenter對象,先看一下咱們在引用以前代碼是怎麼樣的吧github

package com.qianmo.myview2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.qianmo.myview2.presenter.HiPresenterImpl;

public class MainActivity extends AppCompatActivity {

    private HiPresenterImpl hiPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
    //直接new對象
        hiPresenter = new HiPresenterImpl();
    }
}
   

  這時候引用Dagger2,再看看咱們的代碼架構

   MainActiivty.javaapp

package com.qianmo.myview2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.qianmo.myview2.presenter.HiPresenterImpl;

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {

    @Inject
    private HiPresenterImpl hiPresenter;  //這裏改變了 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}

  Presenter.javaide

package com.qianmo.myview2.presenter;
import com.qianmo.myview2.contract.HiContract;

import javax.inject.Inject;

/**
* Created by MVPHelper on 2016/10/20
*/

public class HiPresenterImpl implements HiContract.Presenter{

    @Inject
    public HiPresenterImpl(){

    }

}

  光上面的這兩個標註還不夠,咱們還要建立對應的Module和Component函數

  MainModule.javaui

package com.qianmo.myview2.di.module;

import com.qianmo.myview2.presenter.HiPresenterImpl;

import dagger.Module;
import dagger.Provides;

/**
 * Created by wangjitao on 2017/3/9 0009.
 * E-Mail:543441727@qq.com
 */
@Module
public class MainModule {
    @Provides
    HiPresenterImpl provideHiPresenterImpl() {
        return new HiPresenterImpl();
    }
}

  MainComponent.java

package com.qianmo.myview2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.qianmo.myview2.di.component.DaggerMainComponent;
import com.qianmo.myview2.di.module.MainModule;
import com.qianmo.myview2.presenter.HiPresenterImpl;

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {

    @Inject
    private HiPresenterImpl hiPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerMainComponent.builder().mainModule(new MainModule()).build().inject(this);
        hiPresenter.say();
    }
}

  這樣咱們就簡單的使用了,再來簡單的分析一下流程 :被 @Inject 註解的代碼存在某種聯繫,當代碼執行到 @Inject 的時候程序會自動進入到這個類的構造方法中,若是正巧這個構造方法也被 @Inject 修飾了,那麼系統就會幫咱們自動建立對象。

3,封裝

  由上面的項目咱們進行過分,但咱們封裝的時候,主要是要在activity和fragment來持有Presenter對象,先來封裝Activity,這是目錄

       

  先看一下咱們以前的presenter的建立,在BaseActivity中添加抽象方法,在Mainactivity中重寫方法再new對象

  

      

     先建立Application的Module,Application的話主要是提供上下文環境,而appliacation中的component,只是提供Context展現方法get方法

  AppModule.java

package com.qianmo.mvpproject.di.module;



import com.qianmo.mvpproject.App;
import com.qianmo.mvpproject.di.ContextLife;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

/**
 * Created by wwangjitao on 16/8/7.
 */

@Module
public class AppModule {
    private final App application;

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

    @Provides
    @Singleton
    @ContextLife("Application")
    App provideApplicationContext() {
        return application;
    }


}

  AppComponent.java

package com.qianmo.mvpproject.di.component;



import com.qianmo.mvpproject.App;

import javax.inject.Singleton;
import com.qianmo.mvpproject.di.ContextLife;
import com.qianmo.mvpproject.di.module.AppModule;

import dagger.Component;

/**
 * Created by wangjitao on 16/8/7.
 */

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    @ContextLife("Application")
    App getContext();  // 提供App的Context


}

  而Activity的Module主要是提供Activity和上下文Context對象,對應的Activity的component主要是將提供的對象注入到須要它的地方

     ActivityModule.java

package com.qianmo.mvpproject.di.module;

import android.app.Activity;
import android.content.Context;


import com.qianmo.mvpproject.base.BaseRxPresenter;
import com.qianmo.mvpproject.di.ActivityScope;

import dagger.Module;
import dagger.Provides;

/**
 * Created by codeest on 16/8/7.
 */

@Module
public class ActivityModule {
    private Activity mActivity;

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

    @Provides
    @ActivityScope
    public Activity provideActivity() {
        return mActivity;
    }

    @Provides
    public Context provideContext() {
        return mActivity;
    }

}

  ActivityComponent.java

package com.qianmo.mvpproject.di.component;

import android.app.Activity;


import com.qianmo.mvpproject.di.ActivityScope;
import com.qianmo.mvpproject.di.module.ActivityModule;
import com.qianmo.mvpproject.ui.activity.CheckVersionActivity;

import dagger.Component;

/**
 * Created by codeest on 16/8/7.
 */

@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {

    Activity getActivity();

    void inject(CheckVersionActivity welcomeActivity);


}

  再在BaseActivity中去調用

  BaseActivity.java

package com.qianmo.mvpproject.base;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import javax.inject.Inject;
import com.qianmo.mvpproject.App;
import com.qianmo.mvpproject.R;
import com.qianmo.mvpproject.di.component.ActivityComponent;
import com.qianmo.mvpproject.di.component.DaggerActivityComponent;
import com.qianmo.mvpproject.di.module.ActivityModule;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * Created by wangjitao on 2016/11/8 0008.
 * 基類Activity的封裝
 * 通常使用mvp模式的話會在BaseActivity中進行P和V的初始化綁定
 */
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity implements BaseView {

    //這裏添加了注入
    @Inject
    protected T mPresenter;

    .......省略

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        .......省略
        super.onCreate(savedInstanceState);
        setContentView(getLayout());

        
        //這裏添加了注入的調用
        initInject();

        if (mPresenter != null)
            mPresenter.attachView(this);
       
    }

   
   //添加調用方法
    protected ActivityComponent getActivityComponent(){
        return  DaggerActivityComponent.builder()
                .appComponent(App.getAppComponent())
                .activityModule(getActivityModule())
                .build();
    }

    protected ActivityModule getActivityModule(){
        return new ActivityModule(this);
    }
}

  ok,這樣咱們就封裝了,同理Fragment,這裏就不廢話寫了,下面把github地址貼上,後面打算這些東西寫一個展現類的app,又要處處找接口了,See You Next Time !

相關文章
相關標籤/搜索