概述
-
在2016年5,6月份開始在知乎上看到開發方法,那時候記得是看mvc,mvp,mvvm這三種開發模式區別,后面進一步了解到google在github上開源了使用這3種模式進行Android開發的demo.不同的項目有不同的情況,開發項目是找一個最適合的,而不是性能最好,開發時間最短等。
-
MVP是一種開發模式或者架構,RxJava與Retrofit是兩個庫,前面的是異步的庫,后面的是提供Restful請求的庫,這兩個庫都是為了MVP開發模式服務的。當然,他的適用場景是業務邏輯復雜的項目,也就是解決控制層耦合性太高。
-
Dagger2庫,RxJava庫,Retrofit庫會進行簡單介紹,了解其運作的機制。
Dagger2庫
關鍵概念
-
Inject--你用它告訴Dagger這個類或者字段需要依賴注入
-
Module-- Modules類里面的方法專門提供依賴,所以我們定義一個類,用@Module注解,這樣Dagger在構造類的實例的時候,就知道從哪里去找到需要的依賴
-
Provide--在modules中,我們定義的方法是用這個注解,以此來告訴Dagger我們想要構造對象並提供這些依賴。
-
Component--Components從根本上來說就是一個注入器,也可以說是@Inject和@Module的橋梁,它的主要作用就是連接這兩個部分。 Components可以提供所有定義了的類型的實例,比如:我們必須用@Component注解一個接口然后列出所有的@Modules組成該組件,如 果缺失了任何一塊都會在編譯的時候報錯。所有的組件都可以通過它的modules知道依賴的范圍。
-
Scope-- Scopes可是非常的有用,Dagger2可以通過自定義注解限定注解作用域。后面會演示一個例子,這是一個非常強大的特點,因為就如前面說的一樣,沒 必要讓每個對象都去了解如何管理他們的實例。在scope的例子中,我們用自定義的@PerActivity注解一個類,所以這個對象存活時間就和 activity的一樣。簡單來說就是我們可以定義所有范圍的粒度(@PerFragment, @PerUser, 等等)。
-
Qualifier--當類的類型不足以鑒別一個依賴的時候,我們就可以使用這個注解標示。例如:在Android中,我們會需要不同類型的context,所以我們就可以定義 qualifier注解“@ForApplication”和“@ForActivity”,這樣當注入一個context的時候,我們就可以告訴 Dagger我們想要哪種類型的context。
如何在MVP中使用
創建BasePresenter與BaseView
-
MVP架構中M與V通過P進行交互,activity用來顯示不再負責具體業務邏輯,職責明確,便於測試;
-
BasePresenter與BaseView抽象出視圖中公共的行為,可以在activity或者fragment中實現BaseView的子類,渲染界面;
public interface BasePresenter {
//訂閱
void subscribe();
//解訂
void unsubscribe();
}
public interface BaseView<T> {
void setPresenter(T presenter);//view中設置處理器
}
創建處理器(MVP中的P)
1.新建MineContract,view與presenter的抽象接口集合,相當於講下要去做那些事情
public interface MineContract {
interface View extends BaseView<Presenter>{
void login_success(String response);
void login_failure(String msg);
void network_exception(int errcode);
void network_normal();
}
interface Presenter extends BasePresenter{
void login(User user);
}
2.新建MinePresenter,實現MineContract.Presenter接口方法,相當於事情具體怎么去做
public class MinePresenter implements MineContract.Presenter {
private final static String TAG="MinePresenter";
private MineContract.View mView;
public MinePresenter(MineContract.View view) {
this.mView = view;
this.mView.setPresenter(this);
}
@Override
public void subscribe() {
}
@Override
public void unsubscribe() {
}
@Override
public void login(User user) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mView.login_success("success");
Log.d(TAG,"logined");
}
},500);
}
}
創建實體(MVP中的M)
創建User類,作為登錄測試
public class User {
private String uId;
private String uName;
private String uPwd;
private String uType;
private String uLevel;
//省略set與get方法
}
創建界面(MVP中的V)
- 創建MainActivity,采用嵌套fragment方式,繼承自
FragmentActivity
public class MainActivity extends FragmentActivity {
private FragmentManager mFragMgr;
@Inject
MinePresenter presenter;
private MineFragment mineFragment;
private final String MINE = "Mine";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragMgr = getSupportFragmentManager();
initFragments();
showFragments(MINE,true);
}
private void initFragments() {
mineFragment = new MineFragment();
}
private void showFragments(String tag, boolean init) {
FragmentTransaction trans = mFragMgr.beginTransaction();
if (init) {
trans.add(R.id.main_content, getFragmentByTag(tag), tag);
trans.addToBackStack(tag);
} else {
trans.replace(R.id.main_content, getFragmentByTag(tag), tag);
}
trans.commit();
}
private Fragment getFragmentByTag(String tag) {
if (MINE.equals(tag)) {
return mineFragment;
}
return null;
}
}
- 創建MineFragment,需要實現
implements MineContract.View
接口
public class MineFragment extends Fragment implements MineContract.View {
//省略部分代碼
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
uName = (LikeEditText) view.findViewById(R.id.uName);
uPwd = (LikeEditText) view.findViewById(R.id.uPwd);
loginBtn = (Button) view.findViewById(R.id.login_btn);
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
User user=new User();
user.setuName(uName.getText().toString());
user.setuPwd(uPwd.getText().toString());
minePresenter.login(user);
}
});
}
前面講的都是mvp架構基本搭建,下面是如何運用dagger2;
創建提供應用實例的AppComponent
一個應用在創建時會產生唯一的Application對象,可以在應用的onCreate
函數創建,下面有幾個步驟:
1.創建提供應用對象的Component
1.1創建提供應用對象的Module
@Module
public class AppModule {
private Context mContext;
public AppModule(Context context){
this.mContext=context;
}
@Provides
public Context provideContext(){
return this.mContext;
}
}
1.2創建AppComponent為其他Component提供依賴
@Component(modules = AppModule.class)
public interface AppComponent {
Context getContext();
}
2.構建AppComponent的實例
public class SampleApplication extends Application {
private AppComponent appComponent;
private static SampleApplication mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance=this;
appComponent=DaggerAppComponent.builder().appModule(new AppModule(this)).build();
}
public static SampleApplication getInstance(){
return mInstance;
}
public AppComponent getAppComponent(){
return appComponent;
}
}
在MainActivity如何自動注入MinePresenter
- 1.修改MinePresenter代碼-構造方法注入
@Inject
public MinePresenter(MineContract.View view) {
this.mView = view;
this.mView.setPresenter(this);
}
- 2.創建MinePresenterModule-提供MineContract.View實例
@Module
public class MinePresenterModule {
private final MineContract.View mView;
public MinePresenterModule(MineContract.View view) {
mView = view;
}
@Provides
MineContract.View provideStatisticsContractView() {
return mView;
}
}
- 3.修改MainComponent
@Component(dependencies = AppComponent.class,modules = MinePresenterModule.class)
public interface MainComponent {
MineFragment inject(MineFragment mineFragment);
MainActivity inject(MainActivity mainActivity);
}
- 4.修改MainActivity代碼-成員變量注入與注入MineFragment
@Inject
MinePresenter presenter;
private void initFragments() {
mineFragment = new MineFragment();
DaggerMainComponent.builder().minePresenterModule(new MinePresenterModule(mineFragment)).appComponent(SampleApplication.getInstance().getAppComponent()).build().inject(this);
}
以上所有的步驟已完成,編譯項目,dagger2自動生成相關類,並完成注入。
總結
- 創建module,一般應用於第三方包對象或者應用對象
- 創建Component,依賴注入器,復雜把注入對象注入到注解成員變量
構造方法注入:在類的構造方法前面注釋@Inject
成員變量注入:在類的成員變量(非私有)前面注釋@Inject
-
開始注入調用注射器的
Inject
方法