Dagger2 是一个注入框架 :简单说就是 对象注入 以前要new 的东西,现在通过Dagger2 直接提供 实现了一定程度的解耦合
一 环境配置
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
全文如下不细说,注意Butterknife 的原始自动生成代码用的 不是Apt 所以会发生冲突 将他的改成这样就都可以用了
apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.butterknife'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "com.example.cuizehui.estore"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//dagger2和butterknife冲突
packagingOptions{
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
}
dependencies {
apply plugin: 'com.neenbedankt.android-apt'
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
/* apt 'com.google.dagger:dagger-compiler:2.10-rc4'
*/
//dagger2
apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0'
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:design:26.+'
compile 'com.android.support:support-v4:26.+'
//butterknife
compile 'com.jakewharton:butterknife:8.8.1'
/*annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
*/
//只需要改这一句
apt 'com.jakewharton:butterknife-compiler:+'
// circleimagerview
compile 'de.hdodenhof:circleimageview:2.1.0'
testCompile 'junit:junit:4.12'
provided 'org.glassfish:javax.annotation:10.0-b28'
}
二 根据框架结构分三层
Application -->Activity --> view/fragment 大多数情况下都是这三层
参考文章:
http://www.jianshu.com/p/f4180ad30317
1
Application: (因为ApplictionComponent 是Activity 的依赖项所以 在生成其他Component 时 需要依赖项的对象)
APPComponet的创建:
public class MyApplication extends Application
{
//全局单例 注入器 并给其他注入器提供依赖
private ApplicationComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
initAppComponent();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void initAppComponent(){
appComponent= DaggerApplicationComponent
.builder()
.applicationModule(new ApplicationModule(this))
.build();
}
public static MyApplication getInstance(Context context){
return (MyApplication)context.getApplicationContext();
}
public ApplicationComponent getAppComponent(){
return appComponent;
}
}
AppComponent 文件(是一个接口文件 加注释 因为这里使用了单例模式所以依赖项后面要加作用范围 也就是作用域@注解):
package com.example.cuizehui.estore.interfaces;
import android.app.Application;
import com.example.cuizehui.estore.MainActivity;
import com.example.cuizehui.estore.module.ApplicationModule;
import javax.inject.Singleton;
import dagger.Component;
/**
* Created by cuizehui on 17-9-13.
* * 注入器
*/
@Singleton
@Component (modules = ApplicationModule.class)
public interface ApplicationComponent {
Application getApplication();
}
AppModule:文件 只是简单的提供了一个APP对象
package com.example.cuizehui.estore.module;
import android.app.Application;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class ApplicationModule {
private Application application;
public ApplicationModule(Application application){
this.application=application;
}
@Provides
@Singleton
public Application provideApplication(){
return application;
}
}
2
MainActivity:
MainActivityComponet(由于前面的单例依赖项后面要加作用范围 也就是作用域@PreActivity):
package com.example.cuizehui.estore.interfaces;
import com.example.cuizehui.estore.MainActivity;
import com.example.cuizehui.estore.PreActivity;
import com.example.cuizehui.estore.module.MainActivityModule;
import dagger.Component;
/**
* Created by cuizehui on 17-9-14.
*
*/
@PreActivity
@Component (modules = MainActivityModule.class,dependencies = ApplicationComponent.class)
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
PreActivity():
package com.example.cuizehui.estore;
import javax.inject.Scope;
@Scope
public @interface PreActivity {
}
MainActivityModule:(这里实现了对一个listview adapter对象的创建和提供)
package com.example.cuizehui.estore.module;
import android.util.Log;
import java.util.ArrayList;
import dagger.Module;
import dagger.Provides;
@Module
public class MainActivityModule {
//mainActivity 引用的获取 ,方便fragment 获取
private MainActivity mainActivity;
public MainActivityModule(MainActivity mainActivity) {
this.mainActivity=mainActivity;
}
@Provides
@PreActivity
MainActivity provideMainActivity() {
return mainActivity;
}
@PreActivity
@Provides
public ArrayList<BasePagerView> providePagerViews(){
ArrayList<BasePagerView> pagerViews=new ArrayList<>();
pagerViews.add(new HomepagerView(mainActivity));
pagerViews.add(new ShopPagerView(mainActivity));
pagerViews.add(new OrderPagerView(mainActivity));
pagerViews.add(new MinePagerView(mainActivity));
return pagerViews;
}
//通过参数的方法 也能进入到上面的代码 获取到对象 ,另外这段代码可以省略和直接在在MainViewPagerAdapter的构造函数中添加注解的效果一至
@PreActivity
@Provides
public MainViewPagerAdapter providemainViewPagerAdapter(ArrayList<BasePagerView> pagerViewslist){
MainViewPagerAdapter mainViewPagerAdapter=new MainViewPagerAdapter(pagerViewslist);
return mainViewPagerAdapter;
}
}
MainActivityComponet的注入(在MainAcitivity中完成):
MainActivityComponent mainActivityComponent= DaggerMainActivityComponent
.builder()
.applicationComponent(appComponent)
.mainActivityModule(new MainActivityModule(this))
.build();
mainActivityComponent.inject(this);
这样的注入也可以在BaseActivity 中写好了接口方便 继承BaseActivity的Activity 进行注入,像这样:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
setupActivityComponent(MyApplication.getInstance(this).getAppComponent());
}
protected abstract void setupActivityComponent(ApplicationComponent appComponent);
3
view (普通类)注入
viewModule:
package com.example.cuizehui.estore.module;
import android.content.Context;
import android.util.Log;
import java.util.ArrayList;
import dagger.Module;
import dagger.Provides;
/**
* Created by cuizehui on 17-9-19.
*/
@Module
public class HomepagerViewModule {
public MainActivity mainActivity;
public HomepagerViewModule(MainActivity mainActivity) {
this.mainActivity=mainActivity;
}
@Provides
public ArrayList<ShopDaTa> provideShopDaTa(){
ArrayList<ShopDaTa> arrayList=new ArrayList<>();
//请求拉取数据放到 arraylist中
//模拟数据
ShopDaTa shopDaTa1=new ShopDaTa();
shopDaTa1.setProductName("dfsfd");
ShopDaTa shopDaTa2=new ShopDaTa();
shopDaTa1.setProductName("df43fd");
arrayList.add(shopDaTa1);
arrayList.add(shopDaTa2);
return arrayList ;
}
@Provides
public HomeViewpagerLVAdapter provideLVadpter(ArrayList<ShopDaTa> arrayList){
Log.d("list.size:",arrayList.size()+"");
HomeViewpagerLVAdapter homeViewpagerLVAdapter=new HomeViewpagerLVAdapter(arrayList,mainActivity);
return homeViewpagerLVAdapter;
}
}
package com.example.cuizehui.estore.interfaces;
import dagger.Component;
@Component(modules = HomepagerViewModule.class)
public interface HomePagerViewComponent {
//注入方法
void inject(HomepagerView homepagerView);
}
HomePagerViewComponent homePagerViewComponent= DaggerHomePagerViewComponent
.builder()
.homepagerViewModule(new HomepagerViewModule(mainActivity))
.build();
homePagerViewComponent.inject(this);
特别要注意注入一定要在使用之前,还需要注意所传的上下文之间的引用!!
参考文章:
Dagger2 入门:
http://www.jianshu.com/p/1d84ba23f4d2
http://www.jianshu.com/p/cd2c1c9f68d4
Dagger2 封装:
http://blog.youkuaiyun.com/u012702547/article/details/52200927http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0519/2892.html
三 ButterKnife在viewHolder下的bind
.........
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ShopDaTa shopDaTa= shopDATAsarrayList.get(i);
LayoutInflater layoutInflater=LayoutInflater.from(context);
ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
}
else {
view =layoutInflater.inflate(R.layout.shop_data_layout,null);
holder = new ViewHolder(view);
// holder.textView =view.findViewById(R.id.productName_tV);
view.setTag(holder);
}
holder.textView.setText(shopDaTa.getProductName().toString());
return view;
}
//在holder中绑定
static class ViewHolder {
@BindView(R.id.productName_tV)
TextView textView;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
参考文章:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0519/2892.html