您的位置:首页 > 理论基础 > 计算机网络

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

2016-11-15 15:49 176 查看
转载请标明出处:

http://blog.csdn.net/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/CSDN_NetRetrofit
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  架构 网络