引进dagger2让我们的网络架构更舒服

本文介绍如何使用Dagger2依赖注入框架整合Retrofit网络请求库,通过具体示例展示了配置过程及如何在BaseActivity中注入ComApi接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请标明出处:

http://blog.youkuaiyun.com/qq_27495349/article/details/53172175
本文出自:【CF凌晨的博客】

前言

    不好意思!!!由于最近比较忙,所以一直没有出文章,在这里跟大家说声 sorry...
    好了,今天抽出一点时间,直接开始吧!!!

dagger2

    这里我们就不多说了,关于dagger2的文章,真的是数不胜数。这里推荐下一篇好文章

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0519/2892.html

引进dagger2

    我们在build.gradle里面引进
    //引进dagger2
    compile 'com.google.dagger:dagger:2.7'
    //dagger2注解
    annotationProcessor 'com.google.dagger:dagger-compiler:2.7'
    //为了annotationProcessor 不需要使用apt
    provided 'javax.annotation:javax.annotation-api:1.3'
    引进之后我们可以就着上篇文章,继续完善,这里为了跟以前代码区分开。
    我新建了一个library项目,并且把核心代码复制过来,具体的大家可以参考源码,先把文件目录发出来

这里写图片描述
这里很简单,只是把核心的东西拉出来了,好处就是为了 如果以后给我们网络包升级或者更换版本的时候,我们就不会关系到我们的主程序,只需要更改library里面的build.gradle就可以

    //retrofit2 转化器 gson
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    //引进Rxjava2.0
    compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
    //log拦截器
    compile 'com.squareup.okhttp3:logging-interceptor:3.3.0'
    就是这里了,如果觉得rx2.0感觉不舒服,完全可以换成低版本,
    但是随便你怎么改版本,也只是library在变,你对于外面引用你的项目没任何关系,毕竟我只关心写接口。。。
    现在我们重新new一个module 来模拟下我们如何引进此lib包。
    这里可能有人会问,为什么不能直接在lib里面直接用module来搞?dagger是不允许,所以就别想了。
    不允许也好啊,毕竟你总不能要求别人一定要跟一定要用dagger2吧!!!
    大家看了上篇文章之后(认真看哦,会的人就不用看了),我们开撸吧。。。。
    首先我们先把我们上篇文章写的接口跟数据模型拿过来,如下

这里写图片描述
相比大家都能看得懂,这里就是我们自己的项目要写的东西,有些人可能会问lib不是已经有了VersionModel了么?这里我这样讲解下,lib里面的VersionModel只是给使用lib的人做个例子(哈哈),也可以不写哈,那好,我们继续往下面写。
现在我们规定要在BaseActivity里面使用,只需要写这句话,那我们怎么实现呢?

    @Inject
    protected ComApi mComApi;
    懂dagger2的都会知道,有Inject那肯定要有Component与Module,不错,那我们来新建一个dagger包,在里面编写Component与Module。
package com.lingchen.testlib.dagger;

import com.lingchen.testlib.BaseActivity;
import com.lingchen.testlib.dagger.module.ApiModule;
import com.lingchen.testlib.dagger.module.NetModule;

import javax.inject.Singleton;

import dagger.Component;

/**
 * Author    lingchen
 * Email     838878458@qq.com
 * Time      2016/11/15
 * Function  主要注入器
 */
//用@Component表示这个接口是一个连接器
@Component(modules = NetModule.class)
@Singleton
public interface MainComponent {
    /**
     * 需要用到这个连接器的对象,就是这个对象里面有需要注入的属性
     */
    void inject(BaseActivity activity);
}
    这是Component的代码,这里看下void inject(BaseActivity activity)方法,这里就是指定了要注入到哪里去。
    仔细的同学可以看到了@Component(modules = NetModule.class)这句话,我们来看看NetModule类
package com.lingchen.testlib.dagger.module;

import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Author    lingchen
 * Email     838878458@qq.com
 * Time      2016/11/14
 * Function  提供网络客户端
 */
@Module
public class NetModule {
    //暂时放在这里
    private static final String URL = "http://bobo.yimwing.com";

    @Singleton
    @Provides
    public Retrofit getRetrofit(OkHttpClient client) {
        return new Retrofit.Builder()
                .baseUrl(URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    @Singleton
    @Provides
    public OkHttpClient getClient(HttpLoggingInterceptor httpLoggingInterceptor) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(10, TimeUnit.SECONDS);
        builder.writeTimeout(10, TimeUnit.SECONDS);
        builder.readTimeout(300, TimeUnit.SECONDS);
        builder.addInterceptor(httpLoggingInterceptor);
        return builder.build();
    }


    @Singleton
    @Provides
    public HttpLoggingInterceptor getInterceptor() {
        return new HttpLoggingInterceptor();
    }
}
    大家看名字,差不多也可以看到,就是提供网络客户端的。我们看到每个方法上面都是有@Singleton这个注解,看下面的解释,不多说了。
    这里加上Singleton,Component就必须加上Singleton,原因大家自己猜哈。
/**
 * Identifies a type that the injector only instantiates once. Not inherited.
 * 标识一个类型的注射器只实例化一次。不继承。
 * @see javax.inject.Scope @Scope
 */
    网络客户端准备好了,那我们就写个ApiModule.java,来提供我们的网络接口
package com.lingchen.testlib.dagger.module;

import com.lingchen.testlib.net.ComApi;
import com.lingchen.testlib.net.ComInterface;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import retrofit2.Retrofit;

/**
 * Author    lingchen
 * Email     838878458@qq.com
 * Time      2016/11/14
 * Function  提供网络接口
 */
@Module
public class ApiModule {

    @Singleton
    @Provides
    public ComApi getComApi(Retrofit retrofit) {
        ComInterface comInterface = retrofit.create(ComInterface.class);
        return new ComApi(comInterface);
    }
}
    好了,这里我们看到了ComApi被实例化了,至于retrofit是怎么出来的,哈哈,多多看上面的文章哈。

写好之后,别忘了把他加在Component里

@Component(modules = {NetModule.class, ApiModule.class})
    现在我们新建一个App继承Application,在这里做一些初始化
package com.lingchen.testlib;

import android.app.Application;

import com.lingchen.testlib.dagger.DaggerMainComponent;
import com.lingchen.testlib.dagger.MainComponent;

/**
 * Author    lingchen
 * Email     838878458@qq.com
 * Time      2016/11/15
 * Function  Application
 */

public class App extends Application {
    public static MainComponent mainComponent;


    @Override
    public void onCreate() {
        super.onCreate();
        initComponent();
    }

    // 使用Dagger2生成的类 生成组件进行构造,并注入
    private void initComponent() {
        mainComponent = DaggerMainComponent.builder()
                .build();
    }

    public static MainComponent component() {
        return mainComponent;
    }

}
好了,我们把以前写的BaseActivity类拿过来,修改下
package com.lingchen.testlib;

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

import com.lingchen.testlib.net.ComApi;

import javax.inject.Inject;

import io.reactivex.disposables.Disposable;
import io.reactivex.internal.disposables.ListCompositeDisposable;

/**
 * Author    lingchen
 * Email     838878458@qq.com
 * Time      2016/11/4
 * Function  所有界面基类
 */

public abstract class BaseActivity extends AppCompatActivity {
    //需要注入ComApi 
    @Inject
    protected ComApi mComApi;

    private ListCompositeDisposable listCompositeDisposable = new ListCompositeDisposable();


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        App.component().inject(this);
        setContentView(getLayoutResID());
        initView();
        initData();
    }

    protected abstract int getLayoutResID();

    protected abstract void initView();

    protected abstract void initData();

    protected void addDisposable(Disposable disposable) {
        if (disposable != null && !disposable.isDisposed()) {
            listCompositeDisposable.add(disposable);
        }
    }

    protected void reDisposable(Disposable disposable) {
        if (disposable != null) {
            listCompositeDisposable.remove(disposable);
        }
    }

    protected void clear() {
        if (!listCompositeDisposable.isDisposed()) {
            listCompositeDisposable.clear();
        }
    }

    @Override
    protected void onDestroy() {
        clear();
        super.onDestroy();
    }
}
    可以看到,此类变成了abstract,增加了几个抽象方法,这里就不多说了。
    注意oncreate方法里的App.component().inject(this),如果不加这个方法,将不会注入ComApi
    //需要注入ComApi 
    @Inject
    protected ComApi mComApi;
    好了,大功告成,我们来看看主界面代码
package com.lingchen.testlib;

import android.widget.TextView;

public class MainActivity extends BaseActivity {
    private TextView mTextView;

    @Override
    protected int getLayoutResID() {
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {
        mTextView = (TextView) findViewById(R.id.tv_poetry);
    }

    @Override
    protected void initData() {
        addDisposable(mComApi.checkVersion()
                .doOnNext(versionModelResBaseModel -> {
                    if (versionModelResBaseModel.isSuccess()) {
                        mTextView.setText(versionModelResBaseModel.getData().getUpdateContent());
                    } else {
                        mTextView.setText("请求失败");
                    }
                })
                .doOnError(throwable -> mTextView.setText(throwable.getMessage()))
                .subscribe());
    }
}
    好了!!!!大功告成了!!!

总结

    由于最近很忙,不能及时出新的文章,还请大家谅解哈!!!我们下期再见喽!!!!!!

源码

https://github.com/CFlingchen/youkuaiyun.comRetrofit

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值