Dagger 之外的第二個選擇

injectMVP

項目背景

依賴注入或者控制反轉思想已經體現在了java web的spring框架中,在android中有關注入的開源項目主要有Dagger2,還有Arouter,但arouter不是專門去做注入的工作,暫不比較.Dagger2比較優秀。在android中MVP是最合適使用依賴注入的場景。但Dagger2有一個缺點,就是比較繁瑣,這個框架就是簡化這個過程,達到輕量級的效果。

Compare

Dragger2的使用demo

需要一個module 類,一個Component接口配合,簡化的代碼如下;

@Module
public class MainModule {
    private IView mIView;

    public MainModule(IView IView) {
        mIView = IView;
    }

    @Provides
    @ActivityScope
    public IView provideIView(){
        return this.mIView;
    }
}

@ActivityScope
@Component(modules = MainModule.class)
public interface MainComponent {
    void inject(MainActivity activity);
}

public class MainActivity extends AppCompatActivity implements IView{

    @Inject
    MainPresenter mMainPresenter;

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

        DaggerMainComponent
                .builder()
                .mainModule(new MainModule(this))
                .build()
                .inject(this);
        mMainPresenter.loadData();
    }

    @Override
    public void loadSucc() {

    }
}

從代碼層面來說,爲了注入一個MainPersenter,要寫這麼多代碼,有種不如不用的感覺,甚至在注入的時候出現new MainModule(this)這樣的代碼,按照道理這個過程應該交由容器來解決,不該暴露該用戶的.

injectMvp的demo

無需配合類,一行代碼實現注入過程,面向接口,不面向具體。

public interface IPresenter  {
    public void loadData();

    public void bindView(IView iView);

    public void unBindView();
}
@Compont(version = 1)
public class MainPresenter2 implements IPresenter {
    private IView mIView;

    @Override
    public void bindView(IView iView) {
        mIView = iView;
    }

    @Override
    public void unBindView() {
        mIView = null;
    }

    @Override
    public void loadData() {
        mIView.loadSucc();
    }

}
public class MainActivity extends AppCompatActivity implements IView{
   @AutoWired
   IPresenter mIPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        InjectManager.getInstance().init(getApplication());//放入application中初始化即可
        InjectManager.getInstance().inject(this);

        mIPresenter.bindView(this);
        mIPresenter.loadData();
    }

    @Override
    public void loadSucc() {

    }
}
小結一下

injectMVP的處理依賴注入達到注入效果,比較簡潔,版本可追述,也遵循了面向接口的思想,但是還是有可提高的地方。下面是具體的介紹以及使用方法。

Configuration

  1. Adding maven url
allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        maven {
            url "https://jitpack.io"
        }
        maven { url 'https://dl.bintray.com/josehan1989/maven' }
    }
}
  1. Adding dependencies and configurations

    dependencies {
        implementation 'com.ca.inject:api:1.0.2'
        annotationProcessor 'com.ca.inject:compile:1.0.2'
        implementation 'com.ca.inject:annotation:1.0.1'
    }
    
  2. Add annotation

    @Compont(version = 1)
    public class MvpPresenter implements IPresenter {
        ...
    }
    
  3. 初始化

    public class MyApp extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            InjectManager.getInstance().init(this);
        }
    }
    

Advanced usage

  1. AutoWire a field

    public class MvpActivity extends AppCompatActivity implements IView{
    
        @AutoWired
        IPresenter mPresenter;
        TextView tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_mvp);
            InjectManager.getInstance().inject(this);
            mPresenter.bind(this);
            tv = findViewById(R.id.tv);
            mPresenter.getTitle();
        }
    
        @Override
        public void refreshTitle(String title) {
            tv.setText(title);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mPresenter.unBind();
        }
    }
    

More features

  1. 高版本會覆蓋低版本,只要往註解定義version就可以。

    @Compont(version = 2)
    public class MvpPresenter2 implements IPresenter {
       ...
    }
    
  2. 有一個情況特殊,就是高版本的實現是通過繼承而不是實現接口的方式,就要額外增加一個KEY,顯示指出根接口(後續定義key的返回時class類型,可以不用制定key,將更方便)

@Compont(version = 3,key = MvpPresenter3.KEY)
public class MvpPresenter3 extends MvpPresenter2 {
    public static final String KEY = "com.hansj.lo.demo.IPresenter";

    public MvpPresenter3(){
        init();
    }

    @Override
    public void getTitle() {
        mIView.refreshTitle("nihaoma");
    }

}

In the last

github url:injectMVP,有興趣的朋友,加入這個項目吧,讓這個項目成爲Dagger2之外的第二個選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章