您的位置:首页 > 其它

Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料

2016-07-14 09:03 281 查看

我是曹新雨,我为自己代言。现在的菜鸟,3年以后我就是大神。为自己加油。微信:aycaoxinyu

Dragger2是什么,我就不再说了。资料一堆,而且里面的注解什么意思,我推荐两篇文章,这两篇都是我精挑细选,一般的文章我是不推荐的。

http://android.jobbole.com/82694/

http://android.jobbole.com/82704/

http://android.jobbole.com/82705/

有了基础的了解,来跟我helloworld吧。

第一步:配置依赖:

//如果你用了butterknife,那么这个com.neenbedankt.gradle.plugins就不用再次引入了
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
apply plugin: 'com.neenbedankt.android-apt'

dependencies {

apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0' // dagger2
//    compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2
provided 'org.glassfish:javax.annotation:10.0-b28'
}


第二步:

走到这步我就遇到了一个坑,DaggerApplicationComponent这个类一直报找不到。

后来才知道,要rebuild一下,因为这个类是自动生成的。

解决了这个,然后跟着别人写代码,才算是入了点门。直到了写一个类的依赖注入,需要写三个东西:

loginComponent

LoginModel

额,是两个就行了。就像:

AppComponent

AppModule

这两个全局的。

然后怎么依赖给它的,我还没弄懂。遇到了三个错误:

Error:(6, 43) 错误: 找不到符号
符号:   类 DaggerAppComponent
位置: 程序包 com.chinaCEB.cebActivity.components


Error:(19, 10) 错误: com.chinaCEB.cebActivity.view.ILoginActivity cannot be provided without an @Provides-annotated method.
com.chinaCEB.cebActivity.view.LoginActivity.loginPresenter
[injected field of type: com.chinaCEB.cebActivity.presenter.LoginPresenter loginPresenter]
com.chinaCEB.cebActivity.presenter.LoginPresenter.<init>(com.chinaCEB.cebActivity.view.ILoginActivity loginActivity)
[parameter: com.chinaCEB.cebActivity.view.ILoginActivity loginActivity]


每当我不懂dragger2的时候,就看一边资料。这样,真的很有帮助。

http://www.jianshu.com/p/c2feb21064bb

AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。

//component都是接口,到时候,dragger2会生成你的实现类。
//就像DaggerAppComponent  你写了AppComponent就会有DaggerAppComponent这个实现类

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
Context context();  // 提供Applicaiton的Context

ThreadExecutor threadExecutor();   // 线程池

ApiService apiService();  // 所有Api请求的管理类

SpfManager spfManager();  // SharedPreference管理类

DBManager dbManager();  // 数据库管理类
}


AppModule: 这里提供了AppComponent里的需要注入的对象。

//可以发现,AppModule和AppComponent 是对应的
//ThreadExecutor threadExecutor();   // 线程池
/*@Provides
@Singleton
ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
return jobExecutor;
}
*/
@Module
public class AppModule {
private final MyApplication application;

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

@Provides
@Singleton
Context provideApplicationContext() {
return application;
}

@Provides
@Singleton
ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
return jobExecutor;
}

@Provides
@Singleton
ApiService providesApiService(RetrofitManager retrofitManager) {
return retrofitManager.getService();
}

@Provides
@Singleton
SpfManager provideSpfManager() {
return new SpfManager(application);
}

@Provides
@Singleton
DBManager provideDBManager() {
return new DBManager(application);
}
}


也就是AppComponent里面全都是对象,AppModule是它的实现。可是这些入参都是谁给的?

终于知道activity是怎么得到的了。

@Module
public class ActivityModule {
private final Activity activity;

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

@Provides
@ActivityScope
Activity activity() {
return this.activity;
}
}

然后:
//  建议写在基类Activity里
protect ActivityModule getActivityModule(){
return new ActivityModule(this);
}


搞了一天,终于搞定了。dragger2. 我知道我可以的。哼哼。

我现在知道完整的dragger2步骤了。

引入依赖之后:

第二步:

写AppComponent

package com.chinaCEB.cebActivity.components;

import android.content.Context;

import com.chinaCEB.cebActivity.App;
import com.chinaCEB.cebActivity.modules.AppModule;

import javax.inject.Singleton;

import dagger.Component;

/**
* Created by niuxiaowei on 16/3/19.
*/
//AppModule: 这里提供了AppComponent里的需要注入的对象。
@Singleton
@Component(modules={AppModule.class})
//AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。
public interface AppComponent {

Context getContext();
void inject(App app);

//    void inject(BaseActivity baseActivity);

//    Test test();

}


只要你按照上面这种方法写的,那么,你的AppComponent 就会被dragger2换一个名字:DaggerAppComponent 。所有的都是。这就是rebuilt的结果。

第三步:

写完了AppComponent,写完了桥,那就该写model了

import android.content.Context;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

/**
* Created by niuxiaowei on 16/3/19.
*/
@Module
public class AppModule {

Context context;

public AppModule(Context context){
this.context = context;
}

@Provides @Singleton
public Context provideContext(){
return context;
}

//    @Provides @Singleton
//    public Test provideTest(){
//        return new Test();
//    }
}


然后重复activity 的component ,module

package com.chinaCEB.cebActivity.components;

import com.chinaCEB.cebActivity.modules.ActivityModule;
import com.chinaCEB.cebActivity.scope.PerActivity;
import com.chinaCEB.cebActivity.view.LoginActivity;

import dagger.Component;

/**
*
* Created by niuxiaowei on 16/3/20.
*/
//ActivityComponent,可以看到有个@ActivityScope注解,这个注解是自定义的,对应Activity的生命周期,Dagger2可以通过自定义注解限定注解作用域。
//ActivityComponent:生命周期跟Activity一样的组件,这里提供了inject方法将Activity注入到ActivityComponent中,通过该方法,将Activity中需要注入的对象注入到该Activity中。
@PerActivity
@Component(dependencies = AppComponent.class,modules = {ActivityModule.class})
public interface ActivityComponent {
void inject(LoginActivity loginActivity);
//    Activity getActivity();
//    void inject(LoginActivity loginActivity);

}


void inject(LoginActivity loginActivity); 必须要写这个去掉不行

activitymodel

package com.chinaCEB.cebActivity.modules;

import android.app.Activity;

import com.chinaCEB.cebActivity.scope.PerActivity;
import com.chinaCEB.cebActivity.view.ILoginActivity;
import com.chinaCEB.cebActivity.view.LoginActivity;

import dagger.Module;
import dagger.Provides;

/**
* 提供baseactivity的module
* Created by niuxiaowei on 16/3/20.
*/
//ActivityModule:注入Activity,同时规定Activity所对应的域是@PerActivity
@Module
public class ActivityModule {

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

//    @Provides @PerActivity
//    public Activity provideActivity(){
//        return activity;
//    }
@Provides
@PerActivity
ILoginActivity provideILoginActivity() {
return (LoginActivity) this.activity;
}
}


model提供你的对象,也就是你用到的对象,初始化你要的present的时候,或者全局用到的对象

@Provides
@PerActivity
ILoginActivity provideILoginActivity() {
return (LoginActivity) this.activity;
}


然后在mvp 的p里面:

public class LoginPresenter {
private IUserbiz userbiz;
private ILoginActivity loginActivity;
private int i = -1;

@Inject
public LoginPresenter(ILoginActivity loginActivity) {
this.loginActivity = loginActivity;
userbiz=new Userbiz();
}


inject一下


不得不说,dragger2很吊。全局 和局部的对象做的很好。

之后再loginactivity:

@Inject
LoginPresenter loginPresenter;

initInject();
private void initInject() {
// 构建Component并注入
getActivityComponent().inject(this);
//        loginPresenter.attachView(this);
}
// 建议写在MyApplication类里
public AppComponent getAppComponent(){
return DaggerAppComponent.builder()
.appModule(new AppModule((App)getApplicationContext()))
.build();
}

//  建议写在基类Activity里
protected ActivityComponent getActivityComponent(){
return  DaggerActivityComponent.builder()
.appComponent(getAppComponent())
.activityModule(getActivityModule())
.build();
}
//  建议写在基类Activity里
protected ActivityModule getActivityModule(){
return new ActivityModule(this);
}


ok,弄了一天,终于可以运行了。

第一,我不知道DraggerAppComment是动态生成的。很坑。

第二,就是原理理解的不到位,导致不知道怎么写。

总结一个:

dragger2 的作用就是依赖注入,并且分model和commpant, 比如okhttp全局一个就行,还有的是页面自己的一些对象,那么就写在自己的modules里面。

说白了就是写两个文件,一个module,一个commpant,而且格式不就是那样的。

哼,我为什么自卑。没有我做不到的。别人可以我也可以。不就是dragger2?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: