0.0 Android開發如今的變化用一個詞來形容就是 :翻天覆地
php
愈來愈多的項目使用了MVP + Rxjava+Retrofit +Dagger2 + DataBinding等等東西。。 可是這些東西對於木有用過的同窗們開起來仍是比較頭疼的。
轉載請標明出處:http://blog.csdn.net/wingichoy/article/details/51981756
網上有不少介紹他們的教程,可是都比較詳細(我聽到有童鞋問:詳細還很差?? 其實他們最好的學習方式仍是邊敲邊踩坑邊學,一下介紹的太詳細,對於初學者只能有 懵逼的效果),因此準備寫一篇比較簡單的博客,來介紹這些東西的簡單用法。你們跟着敲,即便是初學者應該也不會很懵逼。css
開始以前先說說這些東西的做用java
1.MVP 你們都知道 P的做用是讓MV間接擁有骯髒的PY交易,而不是直接讓他們進行交易。
2.Rxjava 響應式編程 0.0 一個特別屌的地方就是你能夠隨便切換線程
3.Retrofit 代替Volley的東東
4.Dagger2 Android 的IOC框架,即控制反轉,也叫依賴注入
4.DataBinding MVVM的東東,用起來比較方便,可讓bean與View綁定,拋棄setText()!react
東西比較多,可是憋怕! 咱們個一個來了解他們最簡單的用法。android
告訴大家個祕密,其實git
MVP 在http://blog.csdn.net/wingichoy/article/details/50893367有簡單的介紹,新司機們能夠先去看看。
以往的MVP 都要定義3個接口 分別是 IModel IView IPresenter。 寫多了你就會發現,太特麼佔地方了。。。 這裏介紹一種解決辦法,就是引用一種契約類。說白了就是三個接口放一塊兒。github
public interface MainContract {
//View 的接口
interface MainView{
void showData(ApiBean.RetDataBean retDataBean);
void showProgressBar();
}
//presenter的接口
interface MainPresenter{
void getMainData();
}
//Model的接口
interface MainModel{
Observable loadMainData();
}
}
在MVP中 M負責業務邏輯(進行io操做) V就是Activity,負責與用戶交互,P就是他倆搞基的橋樑。比如牛郎(M)織女(V),牛郎要和織女見面,必須有橋(P)啊。編程
Dagger就是依賴注入,解耦用的。常見的使用地方就是注入Presenter到Activity中。api
例子以下bash
public class MainActivity extends AppCompatActivity implements MainContract.MainView {
MainContract.MainPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//mPresenter 再也不以new的形式建立
mPresenter = DaggerMainComponent.builder().mainModule(new MainModule(this)).build().getPresenter();
這樣作有什麼好處呢,好比如今的presenter須要一個參數來構造,到後面需求改了,須要兩個了,若是使用new。 只要修改Presenter 又得修改 Activity,0.0 耦合度太!高!了! 若是採用這種方式,就能夠愉快的修改Presenter,無論Presenter怎麼修改,Activity的代碼都不須要改變了。
在app的gradle里加入:
compile "com.google.dagger:dagger:2.4"
apt "com.google.dagger:dagger-compiler:2.4"
provided 'org.glassfish:javax.annotation:10.0-b28'
最頂部加入
apply plugin: 'com.neenbedankt.android-apt'
在project的gradle加入
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
仍是以剛纔的文件爲例子,咱們想要注入presenter,那麼久在presenter的構造器添加註解@Inject
public class MainPresenterImpl implements MainContract.MainPresenter {
private MainContract.MainView mMainView;
private MainContract.MainModel mMainModel;
@Inject
public MainPresenterImpl(MainContract.MainView mainView) {
mMainView = mainView;
mMainModel = new MainModelImpl();
}
以後構建一個Module,用來提供依賴(presenter構造器須要的參數)
@Module
public class MainModule {
private MainContract.MainView mMainView;
//Module的構造器,傳入一個MainView, 提供給Component
public MainModule(MainContract.MainView mMainView) {
this.mMainView = mMainView;
}
//Provides註解表明提供的參數,爲構造器傳進來的
@Provides
public MainContract.MainView inject(){
return mMainView;
};
}
以後構建一個Component,注意上面的註解,表明使用MainModule
@Component(modules = MainModule.class)
public interface MainComponent {
MainPresenterImpl getPresenter();
}
最後在Activity裏進行注入操做
mPresenter = DaggerMainComponent.builder().mainModule(new MainModule(this)).build().getPresenter();
直的注意的是 這個Dagger開頭的Component是在Build的過程當中建立的,若是第一次書寫 ,請先Rebuild。 這樣就完成了presenter的注入。看到這裏你可能已經懵逼了,不要緊,照着多敲幾遍,俗話說, 代碼百遍,其義自現。 其實就是使用Component建立一個Presenter,而Presenter所需的參數都是由Moudule提供的。
在app的gradle里加入
compile "com.jakewharton.rxbinding:rxbinding:0.4.0"
compile "com.jakewharton.rxbinding:rxbinding-design:0.4.0"
在andrid{}中加入
compileSdkVersion 24
buildToolsVersion "24.0.0"
dataBinding {
enabled = true
}
}
首先要改變的是佈局文件,佈局以layout爲跟佈局
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".view.activity.MainActivity">
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:id="@+id/tv_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{phone.phone}" />
</RelativeLayout>
而後在代碼裏 取代系統自己的setContentView(); 以後就能夠對佈局對象進行操做了。
public class MainActivity extends AppCompatActivity implements MainContract.MainView {
private ActivityMainBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
mBinding.tvTest.setText("hello");
}
在layout標籤下 多了個data能夠定義引入類。好比有一個實體RetDataBean,裏面存放了 phone 等信息,就能夠直接在View上顯示實體的信息。
<data>
<variable name="phone" type="com.wingsofts.rxretrofitmvpdagger2databinding.bean.ApiBean.RetDataBean" />
</data>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:id="@+id/tv_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{phone.phone}" />
</RelativeLayout>
上面表明定義一個RetDataBean類變量,名稱爲phone,在android:text裏面去引用他。
而且在Activity中去把數據給加進去
@Override
public void showData(ApiBean.RetDataBean retDataBean) {
mBinding.setPhone(retDataBean);
}
這就是DataBinding的簡單使用
在app的gradle里加入以下代碼
compile "io.reactivex:rxandroid:1.2.0"
compile "io.reactivex:rxjava:1.1.7"
簡單的說一下基本語法。 其實Rx就是Observable和Subscriber之間的骯髒PY交易。 不認識這倆單詞的童鞋能夠先敲個100遍混臉熟。不要怕,就是剛。Observable是事件源,Subscriber是訂閱者,當事件源發生時間的時候,subscriber作出相應的反應,能夠拿去和OnClickListener做對比。 看一個簡單的栗子:
sampleobservalbe.subscribe(new Subscriber<ApiBean>() {
@Override
public void onCompleted() {
//當全部onNext()執行完畢後處罰
}
@Override
public void onError(Throwable e) {
//錯誤的時候觸發
}
@Override
public void onNext(ApiBean apiBean) {
//當sampleObservable發生事件的時候觸發
Log.e("wing","onNext");
}
});
以上代碼就是 一個簡單的Rxjava使用語法。 當sampleObservable事件發生的時候,調用new Subscriber的onNext方法。 此時你可能有疑惑,這個sampleObservable哪裏來的,固然是鍵盤敲出來的了! 在和Retrofit搭配使用的時候,Retrofit的API會返回一個Observable給你,固然網絡的訪問不能再MainThread上,別問我爲啥。而後Rxjava的強大之處就體現出來了,能夠隨意切換線程! 好比咱們拿到Retrofit返回的observable,想讓他在工做線程訪問網絡,直接調用subscribeOn(Schedulers.io()),在拿到數據回到Subscriber的時候,只須要調用
observeOn(AndroidSchedulers.mainThread())便可,徹底拋棄了什麼Handler有木有!!!屌不屌!! 因此以上敘述的代碼以下:
mMainModel.loadMainData()
.observeOn(AndroidSchedulers.mainThread())//拿到數據的時候在主線程
.subscribeOn(Schedulers.io())//訪問數據在工做線程
.subscribe(new Subscriber<ApiBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(ApiBean apiBean) {
mMainView.showData(apiBean.getRetData());
Log.e("wing","onNext");
}
});
Rxjava的簡單用法就介紹到這裏,由於本文的主旨是讓讀者親自輕鬆敲起來,在敲代碼的過程當中踩坑,在踩坑的過程當中成長。若是須要了解更多,推薦:扔物線大神的這篇文章
在app的gradle加入以下代碼
compile "com.squareup.retrofit2:retrofit:2.1.0"
compile "com.squareup.retrofit2:converter-gson:2.1.0"
compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
compile "com.squareup.okhttp3:3.4.1"
compile "com.squareup.okhttp3:logging-interceptor:3.4.1"
compile 'com.google.code.gson:gson:2.4'
前面說了,Retrofit能夠根據接口返回一個Observable對象,下面看看如何使用。
好比我要訪問的接口爲:http://wifikey.org/api/api.php
首先,用GsonFormat生成一個Bean,
以後定義以下接口
public interface DataApi {
@GET("api.php")Observable<ApiBean> getData();
}
在代碼裏使用Retrofit生成retrofit對象
//Constant.HOST =http://wifikey.org/api/
mApi = new Retrofit.Builder().baseUrl(Constant.HOST).addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build().create(DataApi.class);
此時DataApi就建立成功了,調用DataApi的getData()方法,會返回一個Observable對象,接下來怎麼作,你知道了吧。