一个简易的APP,借助豆瓣图书API,根据isbn号查询书籍的信息。重要代码如下
需要在gradle里添加的依赖:
compile 'io.reactivex:rxjava:x.y.z'
compile 'io.reactivex:rxandroid:1.0.1'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
bean:
网络请求返回结果的一个实体类,可由android studio的gsonformat插件自动生成,retrofit结合gson可以将返回的json转换为一个这样的实体对象
public class Detail {
private RatingBean rating;
private String pubdate;
private String title;
public RatingBean getRating() {
return rating;
}
public void setRating(RatingBean rating) {
this.rating = rating;
}
public String getPubdate() {
return pubdate;
}
public void setPubdate(String pubdate) {
this.pubdate = pubdate;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static class RatingBean {
private String average;
public String getAverage() {
return average;
}
public void setAverage(String average) {
this.average = average;
}
}
}
service:
应用retrofit框架所需设置的一个接口,用于设置网络请求的url与参数。
public interface DetailService {
@GET("isbn/{isbn}")
Observable<Detail> getDetail(@Path("isbn") String isbn);
}
utils:
工具类RetrofitHelper,借助单例模式完成对retrofit的一次性配置
public class RetrofitHelper {
private static Retrofit sInstance = null;
public static Retrofit getInstance(){
if (sInstance == null){
synchronized (RetrofitHelper.class){
if (sInstance == null){
sInstance = new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/book/")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //retrofit与rxjava结合必须添加一行
.addConverterFactory(GsonConverterFactory.create()) //添加这个方法后,retrofit就能自动将网络请求的返回结果转化为需要的bean对象
.build();
}
}
}
return sInstance;
}
}
view:
MVP模式中,View层包含一个接口,由Activity实现,并提供给Prestener调用
//DetailView.java
public interface DetailView {
void updateData(Detail detail);
}
//DetailActivity:
public class DetailActivity extends BaseActivity implements DetailView{
TextView tv_title;
TextView tv_points;
TextView tv_date;
//用于测试的数据
String isbn = "9787208094123";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
//Activity中主动调用presenter的方法,实现V向M的交互
new DetailPresenter(this).loadData(isbn);
}
private void initView(){
tv_title = findViewById(R.id.textView1);
tv_date = findViewById(R.id.textView2);
tv_points = findViewById(R.id.textView3);
}
@Override
public void updateData(Detail detail) {
if (detail != null){
tv_title.setText(detail.getTitle());
tv_points.setText(detail.getRating().getAverage());
tv_date.setText(detail.getPubdate());
}
}
}
listener:
设置一个回调接口,由presenter实现,提供给Model调用。Model在处理完数据后主动回调,从而在presenter里调用view的方法,实现M向V的交互
public interface OnLoginListener {
void loginSuccess(User user);
void loginFailed();
}
presenter:
presenter负责作为view和model之间的桥梁,两者只向其提供接口,从而实现view和Model的完全解耦。
public class DetailPresenter implements OnDetailListener {
DetailView mDetailView;
DetailModel mDetailModel;
public DetailPresenter(DetailView detailView) {
mDetailView = detailView;
mDetailModel = new DetailModelImp();
}
public void loadData(String isbn){
mDetailModel.get(isbn,this);
}
@Override
public void getDetailSuccess(Detail detail) {
mDetailView.updateData(detail);
}
@Override
public void getDetailFailed() {
}
}
model:
model层包含一个接口和实现该接口的具体类。接口提供给presenter调用。具体类中实现了操作数据的逻辑(即网络请求是在该层进行并解析、存储结果的)。当数据操作结束后,model需要通过一个回调接口通知presenter更新view层内容。这个接口就是由presenter实现的OnDetailListener。
public interface DetailModel {
void get(String isbn, OnDetailListener detailListener);
}
public class DetailModelImp implements DetailModel{
@Override
public void get(String isbn, final OnDetailListener detailListener) {
Retrofit retrofit = RetrofitHelper.getInstance();
DetailService detailService = retrofit.create(DetailService.class);
detailService.getDetail(isbn)
.observeOn(AndroidSchedulers.mainThread()) //回调方法(即下面的onNext等)将在UI线程执行
.subscribeOn(Schedulers.newThread()) //网络请求将在新线程里执行
.subscribe(new Observer<Detail>() {
@Override
public void onCompleted() {
Log.d("-------","Completed");
}
@Override
public void onError(Throwable e) {
Log.d("-------","Error");
e.printStackTrace();
detailListener.getDetailFailed();
}
@Override
public void onNext(Detail detail) { //这里的detail是执行完网络请求后,得到的请求结果示例
Log.d("-------","Next");
detailListener.getDetailSuccess(detail);
}
});
}
}