版权声明:欢迎分享,但请注明出处,谢谢 https://blog.csdn.net/qq_28057577/article/details/78295179
前言:
前一篇
Android实战(橘子娱乐)-首页(第五篇 Glide加载图片的简单封装)讲解了我们加载显示图片的工具util的具体代码细节,最后提到我们这一节将学习presenter实现将Model层数据传递给View层。
我们先来看我们之前学习MainActivity的部分代码:
public class MainActivity extends BaseActivity implements MainView,
NavigationView.OnNavigationItemSelectedListener,OnRefreshListener,View.OnClickListener{}
@Override
public void getFilmInfos(Film film) {
mIRecyclerView.setRefreshing(false);
/* mList.clear();*/
for (int i=0;i<film.getSubjects().size();i++) {
mList.add(film.getSubjects().get(i));
}
mMainAdapter.notifyDataSetChanged();
}
上面的两段代码片可以看出我们的MainActivity继承了MainView这个接口并实现了
getFilmInfos(Film film)这个接口方法,而我们想要的数据刚好就是来自这里的参数film,当然这个Film类是我们根据接口返回的json生成的bean类,我就不贴出代码了。我们贴出MainView这个接口的代码:
MainView.java
package com.andy.orange.ui.home.view;
import com.andy.orange.bean.Film;
/**
* Created by Andy Lau on 2017/8/10.
*/
public interface MainView {
void getFilmInfos(Film movieInfos);
}
MainView接口看起来好简单,我们来看我们的主角MainPresenterImpl类
package com.andy.orange.ui.home.presenter.impl;
import android.content.Context;
import android.util.Log;
import com.andy.orange.bean.Film;
import com.andy.orange.ui.home.model.MainModel;
import com.andy.orange.ui.home.model.impl.MainModelImpl;
import com.andy.orange.ui.home.presenter.MainPresenter;
import com.andy.orange.ui.home.view.MainView;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Andy Lau on 2017/8/10.
*/
public class MainPresenterImpl implements MainPresenter {
private MainView mainView;
private MainModel mainModel;
private Context cxt;
private static final String TAG ="Andy";
private Film mFilms;
/*
* 带参构造方法
* */
public MainPresenterImpl(Context cxt,MainView mainView){
this.mainView=mainView;
this.cxt=cxt;
Log.d(TAG,"MainPresenterImpl class->MainPresenterImpl()");
mainModel=new MainModelImpl();
}
/*
* 请求获取热门电影
* */
@Override
public void requestHotFilm(int start,int count) {
Log.d(TAG,"MainPresenterImpl class->requestHotFilm()");
Observable<Film> observable=mainModel.loadHotFilm(start,count);
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Film>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Film films) {
mFilms=films;
//mainView.getFilmInfos(mFilms);
Log.d(TAG,"MainPresenterImpl class->onNext()");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG,"MainPresenterImpl class->onComplete()");
mainView.getFilmInfos(mFilms);
}
});
}
}
分析:我们看presenter的代码会发现,在构造方法中我们传入并初始化了一个MainView的实例mianView以及初始化了一个MainModel实例mainModel,这个时候相当于MainPresenter持有了Model和View的对象,然后Presenter可以任意调用他们的方法,当然前提是公开的方法。
public MainPresenterImpl(Context cxt,MainView mainView){
this.mainView=mainView;
this.cxt=cxt;
Log.d(TAG,"MainPresenterImpl class->MainPresenterImpl()");
mainModel=new MainModelImpl();
}
我们再看下面这段代码:
Observable<Film> observable=mainModel.loadHotFilm(start,count);
看到presenter调用了mainModel的
loadHotFilm()方法返回了一个
Observable
<
Film
>
值,这里就是结合了RxJava执行了网络请求后返回的数据集合;接着看后面的代码会有一个订阅者和观察者的概念,不懂的可以先去学习一下RxJava,我们通过链式调用设置订阅到
Schedulers
.
io
()
观察者在主线程
AndroidSchedulers
.
mainThread
()
再通过subscribe()方法传递的Observer<Film>对象将数据集合通过
mainView.getFilmInfos(mFilms);
传递到MainView也就是MainActivity。这里就已经把MainPresenter将Model层获取的数据传递给MainView的过程讲清楚了,但是还有一个问题MainModel又是怎样获取到数据的呢?接下来我们来看看,MainModel的实现代码:
package com.andy.orange.ui.home.model.impl;
import android.util.Log;
import com.andy.orange.api.ApiService;
import com.andy.orange.bean.Film;
import com.andy.orange.ui.home.model.MainModel;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import io.reactivex.Observable;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Andy Lau on 2017/4/24.
*/
public class MainModelImpl implements MainModel {
protected final static String TAG="Andy";
@Override
public Observable<Film> loadHotFilm(int start,int count) {
Retrofit retrofit =
new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(ApiService.MOVIE_BASE_URL_HOT).build();
ApiService apiService = retrofit.create(ApiService.class);
Observable<Film> hotFilm = apiService.getHotFilm(start,count);
Log.d(TAG,"MainModelImpl class->loadHotFilm()");
Log.d(TAG,"MainModelImpl: hotFilm"+hotFilm.toString());
return hotFilm;
}
}
分析:这里网络请求我们用到了Retrofit2.我们通过设置Gson转换和RxJava2调用适配器以及访问基础URL来构建了一个retrofit实例,并通过他的create方法创建一个ApiService然后再调用
ApiService类的getHotFilm()来获取网络请求的数据,那我们来看看ApiService的具体实现:
package com.andy.orange.api;
import com.andy.orange.bean.Film;
import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.Path;
import retrofit2.http.Query;
/**
* Created by Andy Lau on 2017/8/10.
*/
public interface ApiService {
public static final String MOVIE_BASE_URL_HOT = "https://api.douban.com/v2/";
public static final String MUSIC_BASE_URL = "http://tingapi.ting.baidu.com/v1/restserver/";
//获取热门电影
@GET("movie/top250")
Observable<Film> getHotFilm(@Query("start") int start, @Query("count") int count);
}
分析:看上面的代码可以看出是通过retrofit2发起的Get请求,根据MianModelImpl的baseUrl设置可以拼接出访问路径:
https://api.douban.com/v2/movie/top250?start=0&count=1 当然参数是我随便加上去的。通过Retrofit+RxJava的组合开起来网络请求很简洁对不对,微笑脸!!!