转载请标明出处:
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());
}
}
好了!!!!大功告成了!!!
总结
由于最近很忙,不能及时出新的文章,还请大家谅解哈!!!我们下期再见喽!!!!!!