Android-Dagger2Android-Rxjava&retrofit&daggerAndroid开发

Hement:关于项目中的Dagger2的使用(三)

2018-12-07  本文已影响3人  仕明同学

依赖注入的原理

public class MovieLister {
    private MovieFinder finder;
    public MovieLister() {
        finder = new MovieFinderImpl();
    }
    public Movie[] moviesDirectedBy(String arg) {
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }
    ...
}
public interface MovieFinder {
    List findAll();
}
public class MovieLister {
    private MovieFinder finder;
    public MovieLister(MovieFinder finder) {
        this.finder = finder;
    }
    ...
}
public class MovieLister {
    s...
    public void setFinder(MovieFinder finder) {
        this.finder = finder;
    }
}
public interface InjectFinder {
    void injectFinder(MovieFinder finder);
}
class MovieLister implements InjectFinder {
    ...
    public void injectFinder(MovieFinder finder) {
      this.finder = finder;
    }
    ...
}

Hement中Dagger2的使用

   //dagger2
    api "com.google.dagger:dagger:2.15"
    compileOnly 'org.glassfish:javax.annotation:10.0-b28'
@Module
public class ActivityModule {
    private Activity mActivity;

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

    @Provides
    Activity provideActivity() {
        return mActivity;
    }

    @Provides
    @ActivityContext
    Context providesContext() {
        return mActivity;
    }
}


@Module
public class ApplicationModule {

    protected final HementApplication mApplication;

    public ApplicationModule(HementApplication application) {
        mApplication = application;
    }

    @Provides
    Application provideApplication() {
        return mApplication;
    }

    @Provides
    @ApplicationContext
    Context provideContext() {
        return mApplication;
    }


    @Provides
    @Singleton
    IRemoteServer provideRibotsService() {
        return IRemoteServer.Creator.newHementService();
    }
}
@PerActivity
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {

    /**
     * 注入activity
     * @param mainActivity
     */
    void inject(MainActivity mainActivity);

    /**
     * 每一个类都得单独的注入
     * @param baseActivity
     */
    void inject(NetWorkActivity baseActivity);

    void inject(SPreferencesActivity sPreferencesActivity);

    void inject(DBNetWorkDemoActivity dbDemoActivity);

    void inject(RxEventBusActivity rxEventBusActivity);

    void inject(RxPermissionsActivity rxPermissionsActivity);

    void inject(ImageLoaderActivity imageLoaderActivity);
}
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

    @ApplicationContext
    Context context();
    Application application();

    IRemoteServer remoteServer();

    PreferencesHelper preferencesHelper();

    DatabaseHelper databaseHelper();

    DataManager dataManager();

    RxEventBus eventBus();
}

@Scope //  Scope 的用法,@Scope是元注解,是用来标注自定义注解的
@Retention(RetentionPolicy.RUNTIME)
public  @interface ConfigPersistent {
}
@ConfigPersistent
public class NetWorkPresenter  extends BasePresenter<NetWorkView> {
    .....
}
@ConfigPersistent
@Component(dependencies = ApplicationComponent.class)
public interface ConfigPersistentComponent {

    ActivityComponent activityComponent(ActivityModule activityModule);
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationContext {
}
@Singleton
public class DbOpenHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "hement.db";
    public static final int DATABASE_VERSION = 1;

    @Inject
    public DbOpenHelper(@ApplicationContext Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
}

Hement中BaseActivity、BaseFragment关于Dagger2的封装

    private static final LongSparseArray<ConfigPersistentComponent> sComponentsMap = new LongSparseArray<>();
   @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建ActivityComponent,如果配置更改后调用缓存的ConfigPersistentComponent,则重用它。
        mActivityId = savedInstanceState != null ? savedInstanceState.getLong(KEY_ACTIVITY_ID) : NEXT_ID.getAndIncrement();

        ConfigPersistentComponent configPersistentComponent = sComponentsMap.get(mActivityId, null);
        if (null == configPersistentComponent) {
            Timber.tag(getClassName()).i("创建新的configPersistentComponent id=%d",mActivityId);
            configPersistentComponent = DaggerConfigPersistentComponent.builder()
                    .applicationComponent(HementApplication.get(this).getComponent())
                    .build();
            sComponentsMap.put(mActivityId, configPersistentComponent);
        }
        mActivityComponent = configPersistentComponent.activityComponent(new ActivityModule(this));

        //状态栏的颜色
        QMUIStatusBarHelper.setStatusBarLightMode(this);
    }

  private static final AtomicLong NEXT_ID = new AtomicLong(0);
 NEXT_ID.getAndIncrement()
package com.shiming.hement.ui.base;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import android.support.v7.app.AppCompatActivity;

import com.shiming.base.ui.QMUIActivity;
import com.shiming.base.utils.QMUIDisplayHelper;
import com.shiming.base.utils.QMUIStatusBarHelper;
import com.shiming.hement.HementApplication;
import com.shiming.hement.injection.component.ActivityComponent;
import com.shiming.hement.injection.component.ConfigPersistentComponent;
import com.shiming.hement.injection.component.DaggerConfigPersistentComponent;
import com.shiming.hement.injection.module.ActivityModule;

import java.util.concurrent.atomic.AtomicLong;

import timber.log.Timber;

import static com.shiming.base.BaseApplication.getContext;

/**
 * <p>
 *  抽象应用程序中的其他活动必须实现的活动。它处理Dagger组件的创建,并确保ConfigPersistentComponent的实例跨配置更改存活。
 * </p>
 *
 * @author shiming
 * @version v1.0
 * @since 2018/11/28 10:04
 */

public class BaseActivity extends QMUIActivity {

    private static final String KEY_ACTIVITY_ID = "KEY_ACTIVITY_ID";
    /**
     * AtomicLong是作用是对长整形进行原子操作。 线程安全
     */
    private static final AtomicLong NEXT_ID = new AtomicLong(0);
    /**
     * java1.8中新加入了一个新的原子类LongAdder,该类也可以保证Long类型操作的原子性,
     * 相对于AtomicLong,LongAdder有着更高的性能和更好的表现,可以完全替代AtomicLong的来进行原子操作
     * 但是对 java的版本有要求,这里就不使用 LongAdder了
     */
   // private static final LongAdder NEXT_ID = new LongAdder();

    /**
     * LongSparseArray是android里为<Long,Object> 这样的Hashmap而专门写的类,目的是提高效率,其核心是折半查找函数(binarySearch)。
     * SparseArray仅仅提高内存效率,而不是提高执行效率
     * ,所以也决定它只适用于android系统(内存对android项目有多重要)SparseArray不需要开辟内存空间来额外存储外部映射,从而节省内存。
      */
    // https://www.jianshu.com/p/a5f638bafd3b   常用集合的原理分析 Dagger does not support injection into private fields
    private static final LongSparseArray<ConfigPersistentComponent> sComponentsMap = new LongSparseArray<>();

    private long mActivityId;

    private ActivityComponent mActivityComponent;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建ActivityComponent,如果配置更改后调用缓存的ConfigPersistentComponent,则重用它。
        mActivityId = savedInstanceState != null ? savedInstanceState.getLong(KEY_ACTIVITY_ID) : NEXT_ID.getAndIncrement();

        ConfigPersistentComponent configPersistentComponent = sComponentsMap.get(mActivityId, null);
        if (null == configPersistentComponent) {
            Timber.tag(getClassName()).i("创建新的configPersistentComponent id=%d",mActivityId);
            configPersistentComponent = DaggerConfigPersistentComponent.builder()
                    .applicationComponent(HementApplication.get(this).getComponent())
                    .build();
            sComponentsMap.put(mActivityId, configPersistentComponent);
        }
        mActivityComponent = configPersistentComponent.activityComponent(new ActivityModule(this));

        //状态栏的颜色
        QMUIStatusBarHelper.setStatusBarLightMode(this);
    }
    protected String getClassName(){
        return this.getClass().getSimpleName();
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putLong(KEY_ACTIVITY_ID, mActivityId);
    }

    /**
     * isChangingConfigurations()函数在是Api level 11(Android 3.0.x) 中引入的
     * 也就是用来检测当前的Activity是否 因为Configuration的改变被销毁了,然后又使用新的Configuration来创建该Activity。
     * 常见的案例就是 Android设备的屏幕方向发生变化,比如从横屏变为竖屏。
     */
    @Override
    protected void onDestroy() {
        //检查此活动是否处于销毁过程中,以便用新配置重新创建。
        if (!isChangingConfigurations()) {
            Timber.tag(getClassName()).i("销毁的configPersistentComponent id=%d",mActivityId);
            sComponentsMap.remove(mActivityId);
        }
        super.onDestroy();
    }
    public ActivityComponent activityComponent() {
        return mActivityComponent;
    }

    @Override
    protected int backViewInitOffset() {
        return QMUIDisplayHelper.dp2px(getContext(), 100);
    }

}


上一篇下一篇

猜你喜欢

热点阅读