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 !

相关文章
相关标签/搜索