http://www.jianshu.com/p/7b839b7c5884   推荐 ,照着这个敲完 , 测试成功 , 推荐大家都去看一下 。

下面贴一下我照着这个敲完的代码:

Book实体类 - 用于封装网络请求返回的数据; 这个借助GsonFormat 插件,注意若实体类有实体,一定要手动实现toString();

public interface RetrofitService {
/**
//拼接一个URL然后进行网络请求
//这里我们拼接的URL就是 完整URL:https://api.douban.com/v2/book/search?q=xxx&tag=&start=0&count=1;
//每个URL前面都是以http://www.jianshu.com/开头,我们把这个不变的部分,也叫做baseUrl提出来,放到另一个地方,在下面我们会提到
*/ //将返回值call改为observable
@GET("book/search")
Observable<Book> getSearchBook(@Query("q") String name,
@Query("tag") String tag,
@Query("start") int start,
@Query("count") int count
); /**
* 在每个入参前还多了一个注解。比如第一个入参@Query("q") String name,Query表示把你传入的字段拼接起来
* 这个url需要几个入参你就在这个方法中定义几个入参,每个入参前都要加上Query注解
*
* @GET("book/search")
Call<Book> getSearchBook(@Query("q") String name);//name由调用者传入
@GET("book/search?q=name")
Call<Book> getSearchBook();
**********************************************************
如果入参比较多,就可以把它们都放在Map中
@GET("book/search")
Call<Book> getSearchBook(@QueryMap Map<String, String> options);
***********************************************************
用于替换url中某个字段
@GET("group/{id}/users")
Call<Book> groupList(@Path("id") int groupId);
*******************************************************
指定一个对象作为HTTP请求体
@POST("users/new")
Call<User> createUser(@Body User user);
它会把我们传入的User实体类转换为用于传输的HTTP请求体,进行网络请求
**********************************************************
传送表单数据
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
*/
}
/**
* Created by lemon on 2017/11/20.
* 主要用于Retrofit的初始化:
*/ public class RetrofitHelper {
private Context mCntext;
OkHttpClient client = new OkHttpClient();
GsonConverterFactory factory = GsonConverterFactory.create(new GsonBuilder().create());
private static RetrofitHelper instance = null;
private Retrofit mRetrofit = null; //静态方法getInstance用于获取自身RetrofitHelper的实例化,并且只会实例化一次。
public static RetrofitHelper getInstance(Context context){
if (instance == null){
instance = new RetrofitHelper(context);
}
return instance;
}
private RetrofitHelper(Context mContext){
mCntext = mContext;
init();
} private void init() {
resetApp();
} private void resetApp() {
mRetrofit = new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/")
.client(client)
// 因为接口返回的数据不是我们需要的实体类,我们需要调用addConverterFactory方法进行转换。
// 由于返回的数据为json类型,所以在这个方法中传入Gson转换工厂
.addConverterFactory(factory)
//支持RXJava
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
} //创建RetrofitService的实体类
//getServer方法就是为了获取RetrofitService接口类的实例化。
public RetrofitService getServer(){
return mRetrofit.create(RetrofitService.class);
} }
/**
* Created by lemon on 2017/11/20.
* 这个是和其他层直接调用的接口
* 让你更方便的调用RetrofitService 中定义的方法:
*/ public class DataManager { private RetrofitService mRetrofitService; // 在它的构造方法中,我们得到了RetrofitService 的实例化
// 这样,把RetrofitService 中定义的方法都封装到DataManager 中,
// 以后无论在哪个要调用方法时直接在DataManager 中调用就可以了,
// 而不是重复建立RetrofitService 的实例化,再调用其中的方法。
public DataManager(Context context){
this.mRetrofitService = RetrofitHelper.getInstance(context).getServer();
} public Observable<Book> getSearchBooks(String name, String tag, int start, int count){
return mRetrofitService.getSearchBook(name,tag,start,count);
}
}
/**
* Created by lemon on 2017/11/20.
* presenter主要用于网络的请求以及数据的获取,view就是将presenter获取到的数据进行展示。
*/ public interface Presenter {
void onCreate(); void onStart();//暂时没用到 void onStop(); void pause();//暂时没用到 /*
用于绑定我们定义的View.也就是,你想把请求下来的数据实体类给哪个View就传入哪个View
*/
void attachView(BookView view); void attachIncomingIntent(Intent intent);//暂时没用到 }
public class BookPresenter implements Presenter {

    private DataManager manager;
private CompositeSubscription mCompositeSubscription;
private Context mContext;
private BookView mBookView;
private Book mBook; public BookPresenter (Context mContext){
this.mContext = mContext;
} @Override
public void onCreate() {
manager = new DataManager(mContext);
/**
* CompositeSubscription是用来存放RxJava中的订阅关系的。
* 注意请求完数据要及时清掉这个订阅关系,不然会发生内存泄漏。
* 可在onStop中通过调用CompositeSubscription的unsubscribe方法来取消这个订阅关系,
* 不过一旦调用这个方法,那么这个CompositeSubscription也就无法再用了,要想再用只能重新new一个。
*/
mCompositeSubscription = new CompositeSubscription();
} @Override
public void onStart() { } @Override
public void onStop() {
if (mCompositeSubscription.hasSubscriptions()){
mCompositeSubscription.unsubscribe();
}
} @Override
public void pause() { } //想把请求下来的数据实体类给哪个View就传入哪个View
//在attachView中,我们把BookView传进去。也就是说我们要把请求下来的实体类交给BookView来处理。
@Override
public void attachView(BookView view) {
mBookView = view;
} @Override
public void attachIncomingIntent(Intent intent) { } /**
* 名字和入参都和请求接口RetrofitService中的方法相同。这个方法也就是请求的具体实现过程。
*/
public void getSearchBook(String name,String tag,int start,int count){
mCompositeSubscription.add(manager.getSearchBooks(name, tag, start, count)
.subscribeOn(Schedulers.io()) //请求数据的事件发生在IO线程
.observeOn(AndroidSchedulers.mainThread()) //请求完成后在主线程更新UI
.subscribe(new Observer<Book>() {
@Override
public void onCompleted() {
//所有的事件都完成,可做这些操作
if(mBook != null){
mBookView.onSuccess(mBook);
}
} @Override
public void onError(Throwable throwable) {
//请求过程中发生错误
throwable.printStackTrace();
mBookView.onError("请求失败!!");
} @Override
public void onNext(Book book) {
//这里的BOOK就是我们请求接口返回的实体类
mBook = book;
}
})
);
}
}
/**
* Created by lemon on 2017/11/20.
* View是空的,主要用于和Android中的View区别开来
*/ public interface View {
}
public interface BookView extends View {
/**
* 如果presenter请求成功,将向该方法传入请求下来的实体类,
* 也就是Book,view拿到这个数据实体类后,就可以进行关于这个数据的展示或其他的一些操作
* @param mBook
*/
void onSuccess(Book mBook); /**
* 如果请求失败,就会向这个view传入失败信息,你可以弹个Toast来提示请求失败
* @param result
*/
void onError(String result);
}
public class BookActivity extends AppCompatActivity {

    private TextView text ;
private Button btn ;
private BookPresenter mBookPresenter = new BookPresenter(this); @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
text = (TextView) findViewById(R.id.text);
btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mBookPresenter.getSearchBook("xxx",null,0,1);
}
});
mBookPresenter.onCreate();
mBookPresenter.attachView(mBookView);
} private BookView mBookView = new BookView() {
@Override
public void onSuccess(Book mBook) {
Log.e("log","mbook"+mBook.toString());
text.setText(mBook.toString());
} @Override
public void onError(String result) {
Toast.makeText(BookActivity.this,result, Toast.LENGTH_SHORT).show();
}
}; @Override
protected void onDestroy() {
super.onDestroy();
mBookPresenter.onStop();
}
}

android开发学习 ------- Retrofit+Rxjava+MVP网络请求的实例的更多相关文章

  1. 一步步搭建Retrofit+RxJava+MVP网络请求框架(一)

    首先,展示一下封装好之后的项目的层级结构. 1.先创建一个RetrofitApiService.java package com.xdw.retrofitrxmvpdemo.http; import ...

  2. 一步步搭建Retrofit+RxJava+MVP网络请求框架(二),个人认为这次封装比较强大了

    在前面已经初步封装了一个MVP的网络请求框架,那只是个雏形,还有很多功能不完善,现在进一步进行封装.添加了网络请求时的等待框,retrofit中添加了日志打印拦截器,添加了token拦截器,并且对Da ...

  3. kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式

    今天要说的干货是:以Kotlin,在MVP模式下(OKHttp和 Retrofit+RxJava)网络请求两种实现方式的一个小案例,希望对大家有所帮助,效果图: Retrofit是Square公司开发 ...

  4. Android开发学习之路--网络编程之xml、json

    一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...

  5. Android开发学习总结(一)——搭建最新版本的Android开发环境

    Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...

  6. Android开发学习之路--Android系统架构初探

    环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...

  7. Android开发学习路线的七个阶段和步骤

    Android开发学习路线的七个阶段和步骤           Android学习参考路线     第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和St ...

  8. Android开发学习之路-RecyclerView滑动删除和拖动排序

    Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...

  9. Android开发学习路线图

    Android开发学习方法: Android是一个比较庞大的体系,从底层的Linux内核到上层的应用层,各部分的内容跨度也比较大.因此,一个好的学习方法对我们学习Android开发很重要. 在此建议, ...

随机推荐

  1. 用Qt编写的计算文件MD5值的Demo

    Dialog.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0& ...

  2. js replace()实现全部替换

    var r= "1\n2\n3\n"; //将字母\n替换成分号 alert(r.replace("\n",";")); 结果:1;2\n3 ...

  3. Spark理论学习笔记(一)

    1.调度 分为FIFO和FAIR两种模式 创建调度池:sc.setLocalProperty("spark.scheduler.pool", "pool6") ...

  4. Java IO、BIO、NIO、BIO

    一.什么是IO/NIO: IO:即BIO(Blocking IO):面向流的.同步阻塞式IO:(JDK1.4之前唯一的选择) NIO:面向缓冲的.同步非阻塞式IO:三大核心部分:Selector.Ch ...

  5. vue 移动端开发

    1.vue开发中的路由: 关于require 与import 的区别 2.vue中的mock数据 3.

  6. DataContractAttribute.IsReference

    IsReference property in data contract It determines how objects are serialized, by default, IsRefere ...

  7. SQL Server 数据库备份策略,第一周运行失败的原因

    一般生产库,采用 每10分钟备份Log,每天备份Diff,每周备份Full的策略. 同时存在异地备份.异地备份可使用SQL Server本身的cmdshell存储过程,调用系统命令. 在为新数据库,建 ...

  8. easyui 在日期不满足要求的情况下,让修改链接不可点,或者修改消失

    *****略***** columns:[[ {field:'id',checkbox:true}, {field:'mDate',width:10,title:'菜单日期',align:'left' ...

  9. laya在微信小游戏中加载BitmapFont失效的问题

    发布为微信小游戏后,在微信工具中测试时总是提示加载retry to load TheRed.fnt,并以error告终.由于没有任何出错信息,无奈之下只好阅读源码.对BitmapFont的处理分为两个 ...

  10. poj-1273 Drainage Ditches(最大流基础题)

    题目链接: Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 67475   Accepted ...