本文共 8630 字,大约阅读时间需要 28 分钟。
使用依赖
annotationProcessor 'com.google.dagger:dagger-compiler:2.2' compile 'com.google.dagger:dagger:2.2' provided 'javax.annotation:jsr250-api:1.0'
代码:
/** * @author mazaiting * @date 2018/1/8 */public class Config { public static final String TAG = "Config";}/** * 引擎 * @author mazaiting * @date 2018/1/8 */public class Engine { public Engine(){ Log.e(Config.TAG, "Engine: new Engine()"); }}/** * 轮子 * @author mazaiting * @date 2018/1/8 */public class Wheel { public Wheel(){ Log.e(Config.TAG, "Wheel: new Wheel()"); }}/** * 车座 * @author mazaiting * @date 2018/1/8 */public class Seat { public Seat(){ Log.e(Config.TAG, "Seat: new Seat()"); }}
/** * 车 * @author mazaiting * @date 2018/1/8 */public class Car { private Engine mEngine; private Seat mSeat; private Wheel mWheel; public Car() { mEngine = new Engine(); mSeat = new Seat(); mWheel = new Wheel(); Log.e(Config.TAG, "Car: new Car()"); }}
执行Android单元测试:
/** * @author mazaiting * @date 2018/1/9 */public class CarTest { @Test public void testCar(){ new Car(); }}
使用Dagger2之后,先要创建一个CarModule类,再创建一个CarComponent接口或者抽象类,接下来Ctrl+F9进行编译,如果编译成功,则会生成DaggerCarComponent类(生成的Dagger开头,并且后面为Component组件的接口名/抽象类名),这个类提供注册Module类和注入当前类。
/** * @Module用来管理并提供依赖 * @Provides用来提供依赖 * @author mazaiting * @date 2018/1/8 */@Modulepublic class CarModule { @Provides public Engine provideEngine(){ return new Engine(); } @Provides public Seat provideSeat(){ return new Seat(); } @Provides public Wheel provideWheel(){ return new Wheel(); } }/** * 组件 * @author mazaiting * @date 2018/1/8 */@Component(modules = CarModule.class)public interface CarComponent { /** * 实现注入 * @param car */ void inject(Car car);}/** * 车 * @author mazaiting * @date 2018/1/8 */public class Car { @Inject Engine mEngine; @Inject Seat mSeat; @Inject Wheel mWheel; public Car() { DaggerCarComponent .builder() .carModule(new CarModule()) .build() .inject(this); Log.e(Config.TAG, "Car: new Car()"); }}// Component抽象类实现法/** * @author mazaiting * @date 2018/1/9 */@Component(modules = CarModule.class)public abstract class CarComponent { /** * @param car */ public abstract void inject(Car car);}
执行上一步的Android单元测试,打印结果
1). 给Engine类添加一个构造方法
/** * 引擎 * @author mazaiting * @date 2018/1/8 */public class Engine { public Engine(){ Log.e(Config.TAG, "Engine: new Engine()"); } public Engine(String string){ Log.e(Config.TAG, "Engine: " + string); }}
2). 此时运行之前的Android单元测试,发现它默认调用的是无参数的构造方法
3). 但此时我们就想让它去调用含一个参数的构造方法,我们可以这么做
I>. 自定义一个注解,必须使用@Qualifier修饰器/** * 标识引擎的颜色 * @author mazaiting * @date 2018/1/9 */@Qualifier@Documented@Retention(RetentionPolicy.RUNTIME)public @interface EngineString { String string() default "white";}
II>. 在CarModule中添加一个提供Engine的方法,并使用刚刚自定义的注解
@Modulepublic class CarModule { @Provides public Engine provideEngine(){ return new Engine(); }// ... 省略其他的方法 @EngineString(string = "black") @Provides public Engine provideStringEngine(){ return new Engine("black"); }}
III>. 在Car类中,声明Engine的使用,同样也使用刚刚自定义的注解标识
/** * 车 * @author mazaiting * @date 2018/1/8 */public class Car { @EngineString(string = "black") @Inject Engine mEngine; @Inject Seat mSeat; @Inject Wheel mWheel; public Car() { DaggerCarComponent .builder() .carModule(new CarModule()) .build() .inject(this); Log.e(Config.TAG, "Car: new Car()"); }}
IV>. 使用之前的Android单元测试
@Named 是基于@Qualifier的注解,不过只能传递字符串
@Qualifier 包括但不限于字符串,如枚举等。public class Car { @EngineString(string = "black") @Inject Engine mEngineBlack; @Named(value = "10") @Inject Engine mEngine; @Inject Seat mSeat; @Inject LazymWheelLazy; public Car() { DaggerCarComponent .builder() .carModule(new CarModule()) .build() .inject(this); Log.e(Config.TAG, "Car: new Car()"); } // 使用懒加载的变量 public void useWheel(){ mWheelLazy.get(); }}
新建Android 单元测试
@Test public void testCar1(){ final Car car = new Car(); new Thread(new Runnable() { @Override public void run() { Log.e("tag", "useWheel" + Thread.currentThread()); car.useWheel(); } }).start(); }
单元测试打印结果:
AppModule.java
/** * @author mazaiting * @date 2018/1/9 */@Modulepublic class AppModule { Application mApplication; public AppModule(Application application){ this.mApplication = application; } @Provides @Singleton Application provideApplication(){ return this.mApplication; }}
NetModule.java
/** * @author mazaiting * @date 2018/1/9 */@Modulepublic class NetModule { String mBaseUrl; // Constructor needs one parameter to instantiate. public NetModule(String baseUrl) { this.mBaseUrl = baseUrl; } // Dagger will only look for methods annotated with @Provides @Provides @Singleton // Application reference must come from AppModule.class SharedPreferences providesSharedPreferences(Application application) { return PreferenceManager.getDefaultSharedPreferences(application); } @Provides @Singleton Cache provideOkHttpCache(Application application) { int cacheSize = 10 * 1024 * 1024; // 10 MiB Cache cache = new Cache(application.getCacheDir(), cacheSize); return cache; } @Provides @Singleton Gson provideGson() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); return gsonBuilder.create(); } @Provides @Named("cached") @Singleton OkHttpClient provideOkHttpClientCache(Cache cache) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.cache(cache); return builder.build(); } @Provides @Named("non_cached") @Singleton OkHttpClient provideOkHttpClient() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); return builder.build(); } @Provides @Singleton Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) { Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl(mBaseUrl) .client(okHttpClient) .build(); return retrofit; }}
NetComponent.java
@Singleton@Component(modules = {AppModule.class, NetModule.class})public interface NetComponent { /** * @param activity */ void inject(MainActivity activity);}
完成前三个类之后编译,生成DaggerNetComponent.java.
MyApp.javapublic class MyApp extends Application { private NetComponent mNetComponent; @Override public void onCreate() { super.onCreate(); mNetComponent = DaggerNetComponent .builder() .appModule(new AppModule(this)) .netModule(new NetModule("http://www.baidu.com/")) .build(); } public NetComponent getNetComponent(){ return mNetComponent; }}
MainActivity.java
public class MainActivity extends AppCompatActivity { @Inject @Named("cached") OkHttpClient mClient; @Inject @Named("non_cached") OkHttpClient mOkHttpClient; @Inject SharedPreferences mSharedPreferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);// new Car(); ((MyApp)getApplication()).getNetComponent().inject(this); } // 写数据 public void write(View view){ mSharedPreferences.edit().putString("key", "value").apply(); } // 读数据 public void read(View view){ Toast.makeText(this, mSharedPreferences.getString("key", "string"), Toast.LENGTH_SHORT).show(); }}
activity_main.xml
转载地址:http://rfzeo.baihongyu.com/