mvp框架學習實戰程式碼(配合retrofit+dagger2+rxjava)
阿新 • • 發佈:2019-02-12
【轉載請標明出處http://blog.csdn.net/sw5131899/article/details/51860922,謝謝】
最近一直在學習框架的搭建和使用,對於mvp,很多開發者有自己的獨特見解,褒貶不一。不過我還是覺得它有學習的必要。在某些大專案上,使用mvp可以方便後期的程式碼維護和更新。廢話不多說,開始進入正題。首先是瞭解這些技術,我推薦幾個個人覺得比較好的文件。
rxjava:http://blog.csdn.net/sw5131899/article/details/52064431
dagger2:http://blog.csdn.net/sw5131899/article/details/51839172
retrofit:http://blog.csdn.net/u014165119/article/details/49280779
這些都是基礎的知識,那麼開始框架的搭建。
首先,匯入gradle。為了避免麻煩,我直接把gradle整個文件的內容粘出來。
配置dagger2,建立module和componnet。</pre><pre name="code" class="java">apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.abings.daager2demo" minSdkVersion 19 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } lintOptions { warning 'InvalidPackage' } } buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.0-alpha1' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' apt 'com.google.dagger:dagger-compiler:2.2' provided 'org.glassfish:javax.annotation:10.0-b28' compile 'com.google.dagger:dagger:2.2' compile 'com.jakewharton:butterknife:7.0.1' compile 'com.google.code.gson:gson:2.6.2' compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit2:converter-gson:2.+' compile 'io.reactivex:rxandroid:1.1.0' compile "com.squareup.retrofit:adapter-rxjava:2.0.0-beta2" compile "com.squareup.okhttp:okhttp:2.7.0" }
建立appModule
appModule提供application的例項和APIService的例項,要保證它們是全域性的即單例。加上@Singleton確定作用範圍。@Module public class AppModule { private Application application; public AppModule(Application application){ this.application = application; } @Singleton @Provides public Application providesApplication(){ return application; } @Provides @Singleton APIService provideAPIService() { return RetrofitUtils.createApi(RxJavaCallAdapterFactory.create()); } }
建立applicationComponent
@Singleton
@Component(modules = AppModule.class)
public interface ApplicationComponent {
ActivityComponent plus(ActivityModule activityModule);
DataManager dataManager();
}
Componnet相當於一個橋樑,將ActivityComponent作為其子Component。
建立PerActivity的scope
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}
@Scope and @Singleton
這個註解是用來劃分作用域的,標記當前物件使用範圍。
比如限制物件只能在所有Activity中使用,或者只能在Application中使用,或者只能在Fragment中使用
@Singleton 單例模式全域性共用一個物件 就是@Scope的一個實現
同理
@PerActivity
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {
void inject(LoginActivity loginActivity);
void inject(AActivity aActivity);
}
@Module
public class ActivityModule {
private Activity mActivity;
public ActivityModule(Activity activity){
mActivity = activity;
}
@PerActivity
@Provides
public Activity providesActivity(){
return mActivity;
}
}
現在需要一個App全域性類,提供ActivityComponent物件。
public class App extends Application {
private static ApplicationComponent applicationComponent;
private ActivityComponent activityComponent;
@Inject
DataManager mDataManager;
public static App get(Context context){
return (App) context.getApplicationContext();
}
@Override
public void onCreate() {
super.onCreate();
applicationComponent = DaggerApplicationComponent.builder().appModule(new AppModule(this)).build();
}
public void createActivityComponent(Activity activity){
activityComponent = applicationComponent.plus(new ActivityModule(activity));
}
public ActivityComponent getActivityComponent(){
return activityComponent;
}
public void releaseActivityComponent(){
activityComponent = null;
}
}
dagger所需的配置差不多完成了。接下來就是rxjava和retrofit的配置使用了。
public interface APIService {
@GET("list/{page}")
Observable<JSONObject> getDatas(@Path("page")int page);
}
public class RetrofitUtils {
public static final String BASE_URL = "http://v3.wufazhuce.com:8000/api/movie/";
public static Retrofit singleton;
public static <T> T createApi(Class<T> clazz, Interceptor interceptor, RxJavaCallAdapterFactory factory) {
//if (singleton == null) {
synchronized (RetrofitUtils.class) {
if (singleton == null) {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_URL)
//.addConverterFactory(FastJsonConverterFactory.create())
.addConverterFactory(JsonConverterFactory.create());
// .addConverterFactory(FastJsonConvertFactory.create());
if (interceptor != null) {
builder.client(createInterceptor(interceptor));
}
if (factory != null) {
builder.addCallAdapterFactory(factory);
}
singleton = builder.build();
}
}
return singleton.create(clazz);
}
public static <T> APIService createApi(RxJavaCallAdapterFactory factory) {
return createApi(APIService.class, null, factory);
}
private static OkHttpClient createInterceptor(Interceptor interceptor) {
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(interceptor);
return client;
}
}
這裡想要將retrofit的例項通過dagger提供給下層使用,不用每次都建立retrofit物件。
接下來搭建mvp框架。
public abstract class BaseActivity extends AppCompatActivity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(setlayoutId());
App.get(this).createActivityComponent(this);
inject();
initEvents(savedInstanceState);
}
protected abstract int setlayoutId();
protected abstract void inject();
protected abstract void initEvents(Bundle savedInstanceState);
}
public interface IBaseView<T> {
void showMessage(String mes);
}
public interface Precenter<T extends IBaseView> {
void attachView(T mvpView);
void detachView();
}
具體使用mvp
public class LoginActivity extends BaseActivity implements LoginMvpView {
@Inject
LoginPecenter loginPecenter;
@Bind(R.id.listview)
ListView listView;
@Override
protected int setlayoutId() {
return R.layout.activity_login;
}
@Override
protected void inject() {
App.get(this).getActivityComponent().inject(this);
loginPecenter.attachView(this);
}
@Override
protected void initEvents(Bundle savedInstanceState) {
ButterKnife.bind(this);
}
@Override
public void showMessage(String mes) {
Toast.makeText(LoginActivity.this, mes, Toast.LENGTH_SHORT).show();
}
@OnClick(R.id.button)
public void toA(){
// startActivity(new Intent(this, AActivity.class));
loginPecenter.loadData(0);
}
@Override
public void showData(List list) {
}
}
public interface LoginMvpView extends IBaseView {
void showData(List list);
}
public class LoginPecenter implements Precenter<LoginMvpView> {
private LoginMvpView mvpView;
private final DataManager dataManager;
private Subscription subscription;
@Inject
public LoginPecenter(DataManager dataManager){
this.dataManager = dataManager;
}
@Override
public void attachView(LoginMvpView mvpView) {
this.mvpView = mvpView;
}
@Override
public void detachView() {
mvpView = null;
if (subscription != null){
subscription.unsubscribe();
}
}
public void loadData(int page){
subscription = dataManager.getdatas(page).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<JSONObject>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(JSONObject result) {
Log.i("TAG00",result.toString());
Gson gson = new Gson();
listBean listBean = gson.fromJson(result.toString(), listBean.class);
//省略更新UI邏輯。。
}
});
}
}
在提供APIService例項的時候,需要一個類作為中轉。API是介面,不能提供例項。所以建立一個Datamanager
@Singleton
public class DataManager {
private final APIService apiService;
@Inject
public DataManager(APIService apiService){
this.apiService = apiService;
}
public Observable<JSONObject> getdatas(int page) {
return apiService.getDatas(page);
}
}
重點的類也就這些了,其實我也不能為大家講解清楚,只能意會不能言傳,大家多看看原始碼,有利於學習提高。大家一起加油。
框架在開發中有著不可取代的地位,所以值得我們下功夫去學習。
附上git原始碼: