Dagger2使用方法
Dagger已經加入Google I/O, 是Square開發的依賴注入庫, 發布2.0版本. Dagger表示有向非循環圖(Directed Acyclic Graph, DAGger). 好處和優點有很多, 參考, 所有優秀的開源庫, 本質上都是讓程序更加清晰, 編寫更加容易. 讓我們來看看怎么使用?
主要內容:
(1) 項目的配置環境.
(2) Inject\Module\Component的使用方法.
(3) 結合Retrofit和RxAndroid.
1. 配置
從一個最簡單的HelloWorld開始, 設置build.gradle
, 并添加依賴庫.
buildscript { repositories { jcenter() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } // Lambda表達式 plugins { id "me.tatarka.retrolambda" version "3.2.4" } apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' // 注釋處理 android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "clwang.chunyu.me.wcl_dagger_demo" minSdkVersion 17 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } // 注釋沖突 packagingOptions { exclude 'META-INF/services/javax.annotation.processing.Processor' } // 使用Java1.8 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:recyclerview-v7:23.1.1' // RecyclerView compile 'com.jakewharton:butterknife:7.0.1' // 標注 compile 'com.google.dagger:dagger:2.0.2' // dagger2 compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2 compile 'io.reactivex:rxandroid:1.1.0' // RxAndroid compile 'io.reactivex:rxjava:1.1.0' // 推薦同時加載RxJava compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' // Retrofit網絡處理 compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2' // Retrofit的rx解析庫 compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' // Retrofit的gson庫 provided 'javax.annotation:jsr250-api:1.0' // Java標注 }
Gradle的配置與功能.
android-apt
, 提供dagger2使用編譯生成類的功能.
buildscript { repositories { jcenter() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } apply plugin: 'com.neenbedankt.android-apt' // 注釋處理
retrolambda
, 提供Lambda表達式支持的功能.
// Lambda表達式 plugins { id "me.tatarka.retrolambda" version "3.2.4" } android{ ... // 使用Java1.8 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
recyclerview
, 提供RecyclerView控件的功能.
compile 'com.android.support:recyclerview-v7:23.1.1' // RecyclerView
butterknife
, 提供xml至java的id映射的功能.
compile 'com.jakewharton:butterknife:7.0.1' // 標注
dagger2
, 提供dagger2支持的功能.
compile 'com.google.dagger:dagger:2.0.2' // dagger2 compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2
rx
, 提供rxandroid和rxjava支持的功能.
compile 'io.reactivex:rxandroid:1.1.0' // RxAndroid compile 'io.reactivex:rxjava:1.1.0' // 推薦同時加載RxJava
retrofit
, 提供網絡請求的支持的功能.
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' // Retrofit網絡處理 compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2' // Retrofit的rx解析庫 compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' // Retrofit的gson庫
annotation
, 提供java注釋解析的功能.
provided 'javax.annotation:jsr250-api:1.0' // Java標注
2. 主活動
使用主頁跳轉頁面展示dagger2.
dagger2
主要包含inject
, module
, component
三個部分, 即:
Inject
, 依賴注入dependency injection
, 把定義的類注入聲明.
Module
, 模塊, 提供若干類, 在依賴注入中使用.
Component
, 組件, 注冊若干模塊至項目中.
提供圖接口, 在項目中, 使用注入的類.
/** * Dagger2的圖接口 * <p/> * Created by wangchenlong on 16/1/2. */ public interface DemoGraph { void inject(MainActivity mainActivity); // 注入MainActivity void inject(ReposListActivity reposListActivity); // 注入列表Activity }
組件, 注冊Module, 添加主Module.
/** * 組件 * Created by wangchenlong on 16/1/2. */ @Singleton @Component(modules = {MainModule.class, ApiModule.class}) public interface DemoComponent extends DemoGraph { final class Initializer { private Initializer() { } // No instances. // 初始化組件 public static DemoComponent init(DemoApplication app) { return DaggerDemoComponent.builder() .mainModule(new MainModule(app)) .build(); } } }
如果沒有Module可以暫時不添加, 但是要提供類, 項目注冊需要使用中間類.
DaggerDemoComponent
是自動生成的類, Dagger+類名.
項目的應用, 把Application
添加至組件, 并提供注冊類的圖接口.
/** * 應用信息 * <p/> * Created by wangchenlong on 16/1/2. */ public class DemoApplication extends Application { private static DemoGraph sDemoGraph; private static DemoApplication sInstance; @Override public void onCreate() { super.onCreate(); sInstance = this; buildComponentAndInject(); } public static DemoGraph component() { return sDemoGraph; } public static void buildComponentAndInject() { sDemoGraph = DemoComponent.Initializer.init(sInstance); } }
主活動, 注冊入圖, 并添加跳轉下一頁功能.
/** * 主活動, 注冊類. */ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); DemoApplication.component().inject(this); // 應用注入 } // 跳轉列表視圖 public void gotoReposList(View view) { startActivity(new Intent(this, ReposListActivity.class)); } }
主模塊, 提供Application和Resources.
/** * 主要模塊, 提供Application和resources. * <p/> * Created by wangchenlong on 16/1/2. */ @Module public class MainModule { private final DemoApplication mApp; public MainModule(DemoApplication application) { mApp = application; } @Provides @Singleton protected Application provideApplication() { return mApp; } @Provides @Singleton protected Resources provideResources() { return mApp.getResources(); } }
方法名添加
@Provides
和@Singleton
, 使用時, 添加@Inject
即可. 表示在Module
中創建, 在其他類中, 可以任意注入使用.
方法的參數, 因為沒有調用方法的過程, 所以需要模塊(Module)提供.
3. 其他活動
主要是列表展示GitHub用戶的庫信息, 使用Retrofit和RxAndroid的方法.
使用RecyclerView
展示庫信息, 注入類到圖中, 并注入Github服務
, Rx
分發信息.
/** * 代碼庫列表 * <p> * Created by wangchenlong on 16/1/2. */ public class ReposListActivity extends Activity { @Bind(R.id.repos_rv_list) RecyclerView mRvList; @Inject GitHubService mGitHubService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_repos_list); ButterKnife.bind(this); DemoApplication.component().inject(this); LinearLayoutManager manager = new LinearLayoutManager(this); manager.setOrientation(LinearLayoutManager.VERTICAL); mRvList.setLayoutManager(manager); ListAdapter adapter = new ListAdapter(); mRvList.setAdapter(adapter); loadData(adapter); } // 加載數據 private void loadData(ListAdapter adapter) { mGitHubService.getRepoData("SpikeKing") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(adapter::setRepos); } }
適配器.
/** * RecyclerView的Adapter * <p> * Created by wangchenlong on 16/1/2. */ public class ListAdapter extends RecyclerView.Adapter<ListAdapter.RepoViewHolder> { private ArrayList<Repo> mRepos; // 庫信息 public ListAdapter() { mRepos = new ArrayList<>(); } public void setRepos(ArrayList<Repo> repos) { mRepos = repos; notifyItemInserted(mRepos.size() - 1); } @Override public RepoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_repo, parent, false); return new RepoViewHolder(view); } @Override public void onBindViewHolder(RepoViewHolder holder, int position) { holder.bindTo(mRepos.get(position)); } @Override public int getItemCount() { return mRepos.size(); } public static class RepoViewHolder extends RecyclerView.ViewHolder { @Bind(R.id.item_iv_repo_name) TextView mIvRepoName; @Bind(R.id.item_iv_repo_detail) TextView mIvRepoDetail; public RepoViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } public void bindTo(Repo repo) { mIvRepoName.setText(repo.name); mIvRepoDetail.setText(String.valueOf(repo.description + "(" + repo.language + ")")); } } public static class Repo { public String name; // 庫的名字 public String description; // 描述 public String language; // 語言 } }
GitHub請求接口, 返回Rx的觀察者.
/** * GitHub服務 * <p> * Created by wangchenlong on 16/1/2. */ public interface GitHubService { String ENDPOINT = "https://api.github.com"; // 獲取庫, 獲取的是數組 @GET("/users/{user}/repos") Observable<ArrayList<ListAdapter.Repo>> getRepoData(@Path("user") String user); }
Api模塊, 使用請求接口創建GitHub服務.
/** * 接口模塊 * <p> * Created by wangchenlong on 16/1/2. */ @Module public class ApiModule { @Provides @Singleton protected GitHubService provideGitHubService() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(GitHubService.ENDPOINT) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 添加Rx適配器 .addConverterFactory(GsonConverterFactory.create()) // 添加Gson轉換器 .build(); return retrofit.create(GitHubService.class); } }
不要忘記, 注冊模塊(Module)到組件(Component). 組件組成到應用, 模塊注冊到組件.
dagger2的重要優勢就是省略了很多重復的創建, 直接依賴注入非常簡單.
效果
GitHub下載地址
OK, that’s all! Enjoy It!
來自: http://blog.csdn.net//caroline_wendy/article/details/50450175