一、前言

在学习android architecture components(简称acc)时下载了google官方demo,demo里有一部分是关于dagger+mvvm(mvp)+acc的,本以为阅读起来没有压力但结果却是一脸懵逼,是的,dagger的写法以及注解完全陌生。难道dagger更新了?本着落后就要挨打的原则去google了一番,发现国内资料通篇都是dagger原本的用法,并没有找到我需要的。最后终于在国外网站找到了一篇dagger2.1新用法的介绍,配合dagger官网终于了解了一二,这也坚定了我从头写一篇Dagger文章的决心。

本文适合人群:1、从未了解过dagger,2、仅简单使用API但不了解为何这样使用,3、可以很好的使用并理解dagger,仅需了解新版本(可以直接跳到第四部分)

二、 Dependency Injection(DI)

翻译成中文也就是依赖注入,我们先用一个很简单的例子来了解一下

    class Clothes {
        final int Defense = 5;
    }

    class Pants {
        final int Defense = 10;
    }

    class hero {
        
        void printDefense() {
            Clothes clothes = new Clothes();
            Pants pants = new Pants();
            
            System.out.print("您的角色拥有防御值: "+clothes.Defense + pants.Defense);
        }
    }

这是一段很简单的代码,初始化角色时,拥有衣服裤子两件装备。但仔细查看,在hero类里创建了clothes和pants两个类,造成了耦合,当你修改clothes或pants时很可能影响到hero类。所以我们通常会将上述代码优化如下:

 class hero {
        private Clothes clothes;
        private Pants pants;

        public hero(Clothes clothes, Pants pants) {
            this.clothes = clothes;
            this.pants = pants;
        }

        void printDefense() {
            System.out.print("您的角色拥有防御值: "+clothes.Defense + pants.Defense);
        }
    }

没错放到构造方法里,这就是’依赖注入’了,hero依赖了clothes和pants,同样的,set方法也可以进行依赖注入。大家是不是在不知不觉中也使用过类似的方式呢:)

对比一下两种方式,前者的缺点如下:

1、clothes和pants无法重用,降低了代码的重用性

2、增加了代码的耦合性,一旦clothes和pants更改可能需要修改hero类很多地方

3、很难进行单元测试

好的,接下来我们就开始用依赖注入的方法创建hero

    public static void main(String[] args){
        Clothes clothes = new Clothes();
        Pants pants = new Pants();

        Hero hero = new Hero(clothes, pants);
        hero.printDefense();
    }

这样子看起来没什么大问题,但是当依赖多了,或者依赖也依赖了其他依赖,就会相当臃肿。有点绕吗?没关系我们看代码:


    public static void main(String[] args) {
        Color red = new Color();
        Clothes clothes = new Clothes(red);
        Pants pants = new Pants();
        Shoes shoes = new Shoes();
        Hat hat = new Hat();

        ....

        Hero hero = new Hero(clothes, pants, shoes, hat, ....);
        hero.printDefense();
    }

上面的代码中Clothes又依赖了Color,说不定Color又可能会依赖些什么,加上下面的Pants、Shoes、hat……等等,构造我们的Hero需要太多依赖,这样我们使用hero时就非常不方便,主方法就会越来越难以维护。

三、Dagger基本使用

这样,Dagger就孕育而生了,他是一个DI框架,会让我们的依赖注入工作显得非常轻松。自动生成依赖,而我们只需要添加注解即可。

我们用Dagger的方式来重写上面的代码:


class Clothes {
    final int Defense = 5;

    @Inject
    public Clothes() {
    }
}

class Pants {
    final int Defense = 10;

    @Inject
    public Pants() {
    }
}

class Hero {
    private static final String TAG = "Hero";
    private Clothes clothes;
    private Pants pants;

    @Inject
    public Hero(Clothes clothes, Pants pants) {
        this.clothes = clothes;
        this.pants = pants;
    }

    public void printDefense() {
        Log.e(TAG, "您的角色拥有防御值: " + (clothes.Defense + pants.Defense));
    }
}

是的,就是这么简单,只需要添加@Inject注解,Dagger就能帮我们自动构建Hero对象,当我们使用时就像这样:

Component
interface HeroComponent {
    Hero getHero();
}




    public static void main(String[] args){
//        Clothes clothes = new Clothes();
//        Pants pants = new Pants();

//        Hero hero = new Hero(clothes, pants);
//        hero.printDefense();


        HeroComponent component = DaggerHeroComponent.create();
        Hero hero = component.getHero();
        hero.printDefense();
    }

我们来梳理一下:

1、首先创建一个component接口并添加@component注解,添加获取Hero的方法

2、给Hero构造方法添加@Inject注解,表示需要自动生成该类

3、给依赖类添加@Inject,表示改类也需要自动生成,如此递归添加直到所有依赖都能自动生成

4、构建项目(必须先构建,Dagger会帮你生成一些辅助类),使用名为‘Dagger+YourComponent’的类创建Hero对象

5、愉快的使用吧!

这样一来无论Hero需要多少依赖,我们都可以很简单的生成,不会造成类的臃肿和耦合,使用Hero时不用关心依赖从哪里来,怎么来的,就算Hero或依赖构建方式改变,也不需要修改调用的main函数,很好的解耦。

这时有些童鞋就会问了,如果我需要使用类似Retrofit、OkHttp之类的三方库,而我们却无法去库里添加@Inject注解,该怎么办?没关系,Dagger同样为大家准备了对策:@Module、@Provides

@Module:类似一个仓库,提供Retrofit之流的实例

@Provides:仓库里具体产品的标志,表示该产品对外提供

@Module
public class MyModule {
    
    @Provides
    public Retrofit ProvideRetrofit() {
        return new Retrofit.Builder()
                .baseUrl("www.google.com")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(setupClient())
                .build();
    }
}

这样就写好了一个提供Retrofit的方法,我们还需要将module提交到component:

Component(modules = MyModule.class)
interface HeroComponent {
    Hero getHero();
    Retrofit getRetrofit();
}

这样,我们就可以愉快的使用Retrofit了,使用方式和Hero一样,我就不累述了。

关于其他API大家可以查阅资料,本文重在思路介绍。

建议初学者在阅读以下内容前先了解更多Dagger2的使用,推荐文章:给初学者的Dagger2

因为以下内容仅适合使用过Dagger2的童鞋了!!!

四、Dagger&Android

打起精神,重点来了!!

在讲解重点之前,我们先来看一段代码:

((MyApplication) getApplication())
        .getAppComponent()
        .myActivity(new MyActivityModule(userId))
        .build()
        .inject(this);

在熟悉使用过Dagger2的coder眼中,这段代码几乎贯穿了整个应用程序,每一个activity都会调用同样的代码,相信大家也想尽办法去优化该段代码,包括将其放入Base中或者做了各种各样的封装,可能都不太尽人意(至少笔者没有找到最优解-_-)。

没错!官方这次升级完美的解决了该问题,以前的实现方式我就不多说了,直接讲述新版本方案。

我先按流程走一遍,让大家熟悉熟悉:

1、老规矩,gradle添加依赖

    implementation 'com.google.dagger:dagger-android:2.15'
    implementation 'com.google.dagger:dagger-android-support:2.15' // if you use the support libraries
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.15'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.15'

笔者写的时候最新版为2.15,大家使用时可以更换为官方最新版。

2、创建AppComponent

@Component(modules = {
        AndroidSupportInjectionModule.class,
        AppModule.class,
        ActivityBuilder.class})
public interface AppComponent  extends AndroidInjector<MyApplication> {

    @Override
    void inject(MyApplication app);

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }
}

@Component.Builder:自定义component构造器.如果看过Dagger2源码的童鞋应该知道component是用Builder模式创建的,而这里提供了一个自定义构造器。目前先不管,你甚至可以删除这个Builder都没有影响,Dagger会自动生成,这里我只是想展示一下这个注解

继承了AndroidInjector类,重写了他的Inject方法,这个方法必须写,初始化AppComponent用。

@Component(modules = {
        AndroidSupportInjectionModule.class,
        AppModule.class,
        MainActivityModule.class})

Component注解里添加了需要使用到的Module

AndroidSupportInjectionModule.class:这是Dagger2.1初始化必须的module,由Dagger内部完成,用于提供各种AndroidInjector,我们只需要固定加上即可
AppModule.class:用于Application需要初始化提供的全局module,比如刚刚提到的Retrofit、Okhttp等全局对象
ActivityBuilder.class:这就是我们Activity所需的Module了

前两者我们先不关注,重点看看ActivityBuilder,这和我们以前的使用方式就不大相同了,先来看看他的实现。

3、创建ActivityBuilder

@Module
public abstract class ActivityBuilder {

    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity> bindMainActivity(MainActivityComponent.Builder builder);

}

这里是所有Activity(Fragment等)的Component.builder的集合,需要添加@Binds @IntoMap @ActivityKey注解,暂且不管他们的具体作用,只需要了解@Binds就类似于@Provides就可以了。这个类的作用就是让Dagger知道我们所有的使用地。

4、创建MainActivityComponent

@Subcomponent(modules = {MainActivityModule.class})
public interface MainActivityComponent extends AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    public abstract class Builder extends AndroidInjector.Builder<MainActivity> {
    }
}

需要使用@Subcomponent注解,所以不需要再像以前写Inject之类的方法,modules和以前一样

值得一说的就是内部类Builder,是固定写法,和第三步配套使用。

5、创建MainActivityModule

@Module
public class MainActivityModule {
    @Provides
    MainView provideMainView(MainActivity mainActivity){
        return mainActivity;
    }
    @Provides
    MainPresenter provideMainPresenter(MainView mainView, ApiService apiService) {
        return new MainPresenter(mainView, apiService);
    }
}

这个也和以前一样,提供需要的依赖

不要忘记在Appmodule里添加subComponent注释,如果Activity多了这里就会添加非常多的XXComponent

@Module(subcomponents = {MainActivityComponent.class,XX,XX,XX.....})
public abstract class AppModule {

}

6、初始化Application

public class MyApplication extends Application implements HasActivityInjector {
    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerAppComponent.builder().application(this).build().inject(this);
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }
}

继承HasActivityInjector,重写activityInjector方法,返回一个DispatchingAndroidInjector

然后在oncreate里初始化

7、MainActivity使用

public class MainActivity extends AppCompatActivity implements MainView {
   
    @Inject
    MainPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter.loadMain();
    }

    @Override
    public void onMainLoaded() {
        ((TextView)findViewById(R.id.hw)).setText("hello Dagger2.1");
    }
}

调用AndroidInjection.inject(this)即可,无须再调用一长串Dagger链。

到这里,初步使用就已经结束了,看到这里可能会觉得‘尼玛,好像更麻烦了’,‘绕来绕去头都大了’的感慨,没错,确实是更麻烦了,不过别着急,前面我只是希望大家看看最基础的用法,然后再介绍更简洁的方式,不然大家很可能只会用而不知道其中的来历。

优化一:继承DaggerApplication、DaggerActivity等类

大家应该还记得刚刚提到的Application类的实现,需要:

1、继承HasActivityInjector,2、重写activityInjector方法,3、返回一个DispatchingAndroidInjector

其实不仅是Application,在Activity、Fragment里只要有subcomponent就必须要实现类似的类,举个栗子:

一个Activity里有一个Fragment,fragment需要依赖注入,这时候Activity就必须

1、继承HasFragmentInjector, HasSupportFragmentInjector

2、重写supportFragmentInjector、fragmentInjector方法

3、返回DispatchingAndroidInjector<Fragment>、DispatchingAndroidInjector<android.app.Fragment>

这样的话将会非常麻烦而且重复,但只需要继承了DaggerApplication、DaggerActivity,一切都变得简单了,Dagger2.1都帮你搞定了。这里放出优化后的Application:

public class MyApplication extends DaggerApplication {

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        AppComponent appComponent = DaggerAppComponent.builder().application(this).build();
        appComponent.inject(this);
        return appComponent;
    }

}

对比上面的是不是简单了很多,其实Activity会更明显,而且每个Activity节省的代码加起来是不可计数的,就留给大家自己去尝试了。

优化二:使用注解@ContributesAndroidInjector

这是Dagger2.1最强大的注释,会帮助你节省数以万计的代码,可能你看到之前的介绍还并不希望升级/使用Dagger2.1,但是用了他之后你就会爱上他。

还记得我们的ActivityBuilder吗?多了@Binds @IntoMap @ActivityKey注解,可能之前我们根本没有用到过,并用他们关联到Component.Builder,同样是重复的工作。利用@ContributesAndroidInjector可以省略这一切,于是我们的ActivityBuilder就变成了这样:

@Module
public abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = MainActivityModule.class)
    abstract MainActivity bindMainActivity();

    @ContributesAndroidInjector(modules = {SecondActivityModule.class, SecondFragmentProvider.class})
    abstract SecondActivity bindSecondActivity();
}

而我们的MainActivityComponent类就可以删掉了,是的没错,直接删掉吧!Dagger会帮我们自动生成,这样每个Activity只需要对应一个Module即可,还记得以前每个Activity对应一个Component和一个Module吗?

AppModule也可以不需要列出所有Module了,直接删掉

五、结语

通过优化后,你的代码已经非常简洁了,大家可以尝试用新版的Dagger来写,然后对比以前的方式,你一定会迫不及待使用新版的。

本文完整代码已经提交到GitHub

分为两个分支,master中使用了初始版,complete中使用了简洁的方式,并利用Dagger实现了MVP模式以及绑定Fragment的方式,大家一定要下载阅读,这样更有利于理解。

当然如果觉得有用的话记得点一下star,这是对作者的最大鼓励。

地址:https://github.com/mrqatom/DaggerInjection

下期预告:@Binds详细讲解、Dagger2.1源码讲解

参考文档:

https://medium.com/@iammert/new-android-injector-with-dagger-2-part-1-8baa60152abe

https://medium.com/@harivigneshjayapalan/dagger-2-for-android-beginners-dagger-2-part-i-f2de5564ab25

https://google.github.io/dagger/android

Categories: Android

146 Comments

Amanda Laidlaw · 2019年5月23日 at 上午4:00

I’ve been surfing online more than 3 hours today, yet I never found any interesting article like yours.
It is pretty worth enough for me. In my opinion, if all web owners and bloggers made good content as
you did, the internet will be a lot more useful than ever before.

Tabetha Stephens · 2019年5月23日 at 上午8:54

These are really impressive ideas in about blogging. You have touched some good things here.
Any way keep up wrinting.

Lisa Thrall · 2019年5月23日 at 上午9:45

Ahaa, its nice conversation on the topic of this article here at this blog,
I have read all that, so at this time me also commenting at this place.

Samara Trotta · 2019年5月23日 at 上午10:09

Hello would you mind letting me know which web host you’re using?

I’ve loaded your blog in 3 completely different web browsers and I must say this blog loads a lot quicker then most.
Can you suggest a good internet hosting provider at a reasonable price?

Many thanks, I appreciate it!

Daniel Gold · 2019年5月23日 at 上午10:54

saying the safety should be suspended or kicked out of the game entirely.

Mike Chipman · 2019年5月23日 at 上午11:50

I visited many web sites however the audio quality for audio songs present at this web site is in fact superb.

Melanie Weiskopf · 2019年5月23日 at 下午12:32

Somebody essentially lend a hand to make significantly posts I’d state.
This is the very first time I frequented your website page and thus far?
I surprised with the research you made to create this particular put up
incredible. Great process!

Evelyn Vicini · 2019年5月23日 at 下午1:13

Hi there just wanted to give you a quick heads up. The text in your content seem to be running
off the screen in Ie. I’m not sure if this is a formatting issue or something to do with browser compatibility but I figured I’d post
to let you know. The design look great though!

Hope you get the issue resolved soon. Many thanks

Pauline Lucas · 2019年5月23日 at 下午1:43

I’ve been surfing online more than 2 hours today, yet I never found any interesting
article like yours. It’s pretty worth enough for me. In my opinion, if all site owners and bloggers made good content
as you did, the internet will be much more useful than ever before.

Ryan Hayes · 2019年5月23日 at 下午2:32

What’s up, after reading this remarkable article i am also glad to
share my experience here with mates.

Chad Licea · 2019年5月24日 at 上午10:36

It’s the best time to make some plans for the longer term and it’s time to be
happy. I’ve read this publish and if I may just I wish to suggest you few attention-grabbing issues or suggestions.

Maybe you can write subsequent articles regarding this article.
I wish to learn more issues approximately it!

buy cialis · 2019年3月27日 at 下午10:23

buy cialis

buy cialis

buy viagra · 2019年3月27日 at 下午11:15

buy viagra

buy viagra

buy cialis online · 2019年3月28日 at 上午12:05

buy cialis online

buy cialis online

buy viagra online · 2019年3月28日 at 上午12:53

buy viagra online

buy viagra online

generic cialis · 2019年3月28日 at 上午2:22

generic cialis

generic cialis

generic viagra · 2019年3月28日 at 上午3:05

generic viagra

generic viagra

cialis generic · 2019年3月28日 at 上午3:54

cialis generic

cialis generic

viagra generic · 2019年3月28日 at 上午4:47

viagra generic

viagra generic

tadalafil · 2019年3月28日 at 上午6:10

tadalafil

tadalafil

buy cialis generic tadalafil · 2019年3月28日 at 上午7:53

buy cialis generic tadalafil

buy cialis generic tadalafil

sildenafil 100mg · 2019年3月28日 at 上午8:38

sildenafil 100mg

sildenafil 100mg

cialis · 2019年3月28日 at 上午9:56

cialis

cialis

5mg cialis · 2019年3月28日 at 上午10:32

5mg cialis

5mg cialis

cialis canada · 2019年3月28日 at 上午10:37

cialis canada

cialis canada

cialis online · 2019年3月28日 at 上午10:47

cialis online

cialis online

sildenafil coupons · 2019年3月28日 at 上午11:04

sildenafil coupons

sildenafil coupons

cialis 20 mg · 2019年3月28日 at 下午8:01

cialis 20 mg

cialis 20 mg

buying cialis online · 2019年3月28日 at 下午8:34

buying cialis online

buying cialis online

cialis cost · 2019年3月28日 at 下午8:43

cialis cost

cialis cost

cialis online pharmacy · 2019年3月28日 at 下午8:53

cialis online pharmacy

cialis online pharmacy

sildenafil tablets · 2019年3月28日 at 下午9:10

sildenafil tablets

sildenafil tablets

viagra · 2019年5月17日 at 下午10:07

viagra

viagra

levitra · 2019年5月17日 at 下午11:08

levitra

levitra

generic levitra · 2019年5月18日 at 上午12:19

generic levitra

generic levitra

cheap viagra · 2019年5月18日 at 上午12:51

cheap viagra

cheap viagra

levitra 20 mg · 2019年5月18日 at 上午2:39

levitra 20 mg

levitra 20 mg

cialis vs viagra · 2019年5月18日 at 上午2:42

cialis vs viagra

cialis vs viagra

cialis coupon · 2019年5月18日 at 上午3:19

cialis coupon

cialis coupon

levitra coupon · 2019年5月18日 at 上午3:44

levitra coupon

levitra coupon

dutch women viagra · 2019年5月18日 at 上午3:51

dutch women viagra

dutch women viagra

cialis dosage · 2019年5月18日 at 上午4:22

cialis dosage

cialis dosage

levitra generic · 2019年5月18日 at 上午4:45

levitra generic

levitra generic

female viagra · 2019年5月18日 at 上午4:52

female viagra

female viagra

cialis free trial · 2019年5月18日 at 上午5:22

cialis free trial

cialis free trial

levitra vs viagra · 2019年5月18日 at 上午5:47

levitra vs viagra

levitra vs viagra

generic viagra online pharmacy · 2019年5月18日 at 上午7:24

generic viagra online pharmacy

generic viagra online pharmacy

natural viagra · 2019年5月18日 at 上午8:20

natural viagra

natural viagra

cialis over the counter at walmart · 2019年5月18日 at 上午8:49

cialis over the counter at walmart

cialis over the counter at walmart

over the counter viagra · 2019年5月18日 at 上午9:10

over the counter viagra

over the counter viagra

cialis prices · 2019年5月18日 at 上午11:48

cialis prices

cialis prices

pfizer generic viagra · 2019年5月18日 at 下午12:10

pfizer generic viagra

pfizer generic viagra

cialis side effects · 2019年5月18日 at 下午12:41

cialis side effects

cialis side effects

sildenafil 20 mg tablet vs viagra · 2019年5月18日 at 下午1:03

sildenafil 20 mg tablet vs viagra

sildenafil 20 mg tablet vs viagra

sophia viagra · 2019年5月18日 at 下午2:01

sophia viagra

sophia viagra

viagra coupons · 2019年5月18日 at 下午4:13

viagra coupons

viagra coupons

viagra vs cialis · 2019年5月18日 at 下午4:46

viagra vs cialis

viagra vs cialis

viagra dosage recommendations · 2019年5月18日 at 下午5:09

viagra dosage recommendations

viagra dosage recommendations

viagra for men · 2019年5月18日 at 下午5:36

viagra for men

viagra for men

viagra for sale · 2019年5月18日 at 下午6:08

viagra for sale

viagra for sale

viagra for women · 2019年5月18日 at 下午8:11

viagra for women

viagra for women

cialis generic availability · 2019年5月18日 at 下午8:53

cialis generic availability

cialis generic availability

cialis generic name · 2019年5月18日 at 下午10:14

cialis generic name

cialis generic name

viagra online · 2019年5月18日 at 下午10:45

viagra online

viagra online

cialis generic tadalafil · 2019年5月18日 at 下午11:22

cialis generic tadalafil

cialis generic tadalafil

viagra online canada pharmacy · 2019年5月19日 at 上午12:06

viagra online canada pharmacy

viagra online canada pharmacy

cialis generic tadalafil 10mg · 2019年5月19日 at 上午12:46

cialis generic tadalafil 10mg

cialis generic tadalafil 10mg

viagra pills · 2019年5月19日 at 上午1:23

viagra pills

viagra pills

cialis generic tadalafil 60mg · 2019年5月19日 at 上午2:10

cialis generic tadalafil 60mg

cialis generic tadalafil 60mg

cialis generic tadalafil walmart · 2019年5月19日 at 上午2:24

cialis generic tadalafil walmart

cialis generic tadalafil walmart

viagra prices · 2019年5月19日 at 上午2:45

viagra prices

viagra prices

cialis generic tadalafil for sale · 2019年5月19日 at 上午3:28

cialis generic tadalafil for sale

cialis generic tadalafil for sale

cialis generic tadalafil india · 2019年5月19日 at 上午3:38

cialis generic tadalafil india

cialis generic tadalafil india

viagra sex · 2019年5月19日 at 上午5:39

viagra sex

viagra sex

cialis prices 10mg · 2019年5月19日 at 上午6:40

cialis prices 10mg

cialis prices 10mg

viagra side effects · 2019年5月19日 at 上午6:50

viagra side effects

viagra side effects

cialis prices 100mg · 2019年5月19日 at 上午8:50

cialis prices 100mg

cialis prices 100mg

viagra without a doctor prescription · 2019年5月19日 at 上午9:19

viagra without a doctor prescription

viagra without a doctor prescription

viagra without a doctor prescription from canada · 2019年5月19日 at 上午10:37

viagra without a doctor prescription from canada

viagra without a doctor prescription from canada

cialis prices 20mg · 2019年5月19日 at 上午11:21

cialis prices 20mg

cialis prices 20mg

cialis prices 5mg · 2019年5月19日 at 下午12:17

cialis prices 5mg

cialis prices 5mg

generic cialis tadalafil 20mg · 2019年5月19日 at 下午5:07

generic cialis tadalafil 20mg

generic cialis tadalafil 20mg

cialis prices walmart · 2019年5月19日 at 下午5:17

cialis prices walmart

cialis prices walmart

generic cialis available · 2019年5月19日 at 下午5:55

generic cialis available

generic cialis available

generic cialis pricing · 2019年5月19日 at 下午6:28

generic cialis pricing

generic cialis pricing

best place to buy cialis online without script · 2019年5月19日 at 下午11:10

best place to buy cialis online without script

best place to buy cialis online without script

generic viagra sildenafil citrate · 2019年5月20日 at 上午12:04

generic viagra sildenafil citrate

generic viagra sildenafil citrate

sildenafil · 2019年5月20日 at 上午2:16

sildenafil

sildenafil

buy cialis canada online · 2019年5月20日 at 上午3:06

buy cialis canada online

buy cialis canada online

sildenafil 100mg tablets · 2019年5月20日 at 上午5:31

sildenafil 100mg tablets

sildenafil 100mg tablets

sildenafil 20 mg · 2019年5月20日 at 上午6:39

sildenafil 20 mg

sildenafil 20 mg

buy cialis online without script · 2019年5月20日 at 上午7:12

buy cialis online without script

buy cialis online without script

sildenafil 20 mg tablet · 2019年5月20日 at 上午7:40

sildenafil 20 mg tablet

sildenafil 20 mg tablet

where can i buy cialis over the counter at walmart · 2019年5月20日 at 下午2:34

where can i buy cialis over the counter at walmart

where can i buy cialis over the counter at walmart

where to buy cialis online safely · 2019年5月20日 at 下午3:42

where to buy cialis online safely

where to buy cialis online safely

sildenafil citrate · 2019年5月20日 at 下午4:11

sildenafil citrate

sildenafil citrate

sildenafil citrate 100mg · 2019年5月20日 at 下午4:48

sildenafil citrate 100mg

sildenafil citrate 100mg

sildenafil citrate 20 mg · 2019年5月20日 at 下午5:22

sildenafil citrate 20 mg

sildenafil citrate 20 mg

sildenafil dosage · 2019年5月20日 at 下午6:30

sildenafil dosage

sildenafil dosage

sildenafil generic · 2019年5月20日 at 下午7:04

sildenafil generic

sildenafil generic

sildenafil side effects · 2019年5月20日 at 下午7:33

sildenafil side effects

sildenafil side effects

canadian viagra · 2019年5月21日 at 上午11:53

canadian viagra

canadian viagra

canadian cialis · 2019年5月21日 at 下午1:11

canadian cialis

canadian cialis

canadian pharmacy cialis · 2019年5月21日 at 下午1:59

canadian pharmacy cialis

canadian pharmacy cialis

cost of viagra · 2019年5月21日 at 下午2:25

cost of viagra

cost of viagra

cheap cialis · 2019年5月21日 at 下午2:52

cheap cialis

cheap cialis

cheap cialis generic · 2019年5月21日 at 下午3:41

cheap cialis generic

cheap cialis generic

female viagra pills · 2019年5月21日 at 下午4:04

female viagra pills

female viagra pills

cheap generic cialis · 2019年5月21日 at 下午4:31

cheap generic cialis

cheap generic cialis

generic viagra 100mg · 2019年5月21日 at 下午5:46

generic viagra 100mg

generic viagra 100mg

generic viagra available · 2019年5月21日 at 下午6:35

generic viagra available

generic viagra available

cialis 20mg · 2019年5月21日 at 下午6:59

cialis 20mg

cialis 20mg

generic viagra prices · 2019年5月21日 at 下午7:25

generic viagra prices

generic viagra prices

cialis 5mg · 2019年5月21日 at 下午7:53

cialis 5mg

cialis 5mg

herbal viagra · 2019年5月21日 at 下午8:18

herbal viagra

herbal viagra

cialis black · 2019年5月21日 at 下午8:44

cialis black

cialis black

marley generic viagra · 2019年5月21日 at 下午9:58

marley generic viagra

marley generic viagra

cialis daily · 2019年5月21日 at 下午11:10

cialis daily

cialis daily

online pharmacy viagra · 2019年5月21日 at 下午11:43

online pharmacy viagra

online pharmacy viagra

cialis for sale · 2019年5月22日 at 上午12:06

cialis for sale

cialis for sale

online viagra · 2019年5月22日 at 上午12:31

online viagra

online viagra

cialis from canada · 2019年5月22日 at 上午12:58

cialis from canada

cialis from canada

real viagra · 2019年5月22日 at 上午3:31

real viagra

real viagra

cialis generic canada · 2019年5月22日 at 上午3:52

cialis generic canada

cialis generic canada

viagra 100mg · 2019年5月22日 at 上午5:07

viagra 100mg

viagra 100mg

cialis on line · 2019年5月22日 at 上午5:37

cialis on line

cialis on line

viagra alternative · 2019年5月22日 at 上午6:01

viagra alternative

viagra alternative

viagra cost · 2019年5月22日 at 上午6:54

viagra cost

viagra cost

cialis pills · 2019年5月22日 at 上午8:06

cialis pills

cialis pills

cialis price · 2019年5月22日 at 上午8:56

cialis price

cialis price

cialis vs levitra · 2019年5月22日 at 上午9:47

cialis vs levitra

cialis vs levitra

viagra in action · 2019年5月22日 at 上午11:03

viagra in action

viagra in action

cost of cialis · 2019年5月22日 at 上午11:29

cost of cialis

cost of cialis

viagra on line · 2019年5月22日 at 上午11:56

viagra on line

viagra on line

generic cialis canada · 2019年5月22日 at 下午1:07

generic cialis canada

generic cialis canada

viagra online pharmacy · 2019年5月22日 at 下午1:34

viagra online pharmacy

viagra online pharmacy

generic cialis online · 2019年5月22日 at 下午1:59

generic cialis online

generic cialis online

viagra pill · 2019年5月22日 at 下午2:24

viagra pill

viagra pill

generic cialis tadalafil · 2019年5月22日 at 下午2:48

generic cialis tadalafil

generic cialis tadalafil

generic for cialis · 2019年5月22日 at 下午3:43

generic for cialis

generic for cialis

viagra price · 2019年5月22日 at 下午4:08

viagra price

viagra price

natural cialis · 2019年5月22日 at 下午4:29

natural cialis

natural cialis

no prescription cialis · 2019年5月22日 at 下午5:23

no prescription cialis

no prescription cialis

buy generic cialis · 2019年8月20日 at 上午8:40

buy generic cialis

buy generic cialis

viagra without doctor prescription · 2019年8月25日 at 上午8:43

viagra without doctor prescription

viagra without doctor prescription

tadalafil generic · 2019年8月28日 at 下午5:05

tadalafil generic

tadalafil generic

发表评论

电子邮件地址不会被公开。