android开发学习 ------- Retrofit+Rxjava+MVP网络请求的实例
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网络请求的实例的更多相关文章
- 一步步搭建Retrofit+RxJava+MVP网络请求框架(一)
首先,展示一下封装好之后的项目的层级结构. 1.先创建一个RetrofitApiService.java package com.xdw.retrofitrxmvpdemo.http; import ...
- 一步步搭建Retrofit+RxJava+MVP网络请求框架(二),个人认为这次封装比较强大了
在前面已经初步封装了一个MVP的网络请求框架,那只是个雏形,还有很多功能不完善,现在进一步进行封装.添加了网络请求时的等待框,retrofit中添加了日志打印拦截器,添加了token拦截器,并且对Da ...
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
今天要说的干货是:以Kotlin,在MVP模式下(OKHttp和 Retrofit+RxJava)网络请求两种实现方式的一个小案例,希望对大家有所帮助,效果图: Retrofit是Square公司开发 ...
- Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...
- Android开发学习总结(一)——搭建最新版本的Android开发环境
Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...
- Android开发学习之路--Android系统架构初探
环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...
- Android开发学习路线的七个阶段和步骤
Android开发学习路线的七个阶段和步骤 Android学习参考路线 第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和St ...
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- Android开发学习路线图
Android开发学习方法: Android是一个比较庞大的体系,从底层的Linux内核到上层的应用层,各部分的内容跨度也比较大.因此,一个好的学习方法对我们学习Android开发很重要. 在此建议, ...
随机推荐
- SpringMVC+ajaxFileUpload上传图片 IE浏览器弹下载框问题解决方式
如题,简单记录一下这个问题的解决的方法,导致问题的核心原因是:ajaxfileupload不支持响应头ContentType为application/json的设置.而且IE也不支持这样的格式,而当我 ...
- sql语句,无法绑定由多个部分组成的标识符 "xxx"
String sql = "select TOP 7 news_id,news_title,news_addtime,news_url from web_news_info a" ...
- Linux系统中的运行级别
什么是运行级呢?简单的说,运行级就是操作系统当前正在运行的功能级别. 它让一些程序在一个级别启动,而另外一个级别的时候不启动. Linux系统的有效登录模式有0~9共十种,不过沿用UNIX系统的至多6 ...
- cassandra复制到一个新机器编译失败的问题
在A机器上ant编译后,复制到B机器,在B机器上编译会出错. 原因是载入一些文件时出错,因为路径还是A机器上的路径. 经过与git上的源代码对比,发现多了一个build文件夹,这可能是ant生成的目录 ...
- 如何使用BMap.Point传递变量、存储数据?
在开发中使用到了百度地图进行开发,用于展示企业位置.由于数据量庞大,如果使用marker,将会造成界面卡顿,处理慢的问题. 在查看百度地图API示例是发现了海量点这个东西,还别说对于大数量的点加载起来 ...
- ekhtml使用总结
ekhtml是一个高效SAX方式的HTML解析库. 文件说明 官网下载ekhtml-0.3.2.tar.gz文件解压后,内部包括源码.测试文件.文档.编译脚本等. 如需编译成静态库或动态库后进行集成, ...
- [USACO2012 OPEN] Bookshelf
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2678 [算法] 首先不难想到如下DP : 记f[i]表示前i本书的高度和最小值 显然 ...
- Struts2访问Servlet API的几种方式
struts2提供了三种方式访问servlet API:大致分为两类 1. ActionContext: public static ActionContext getContext() :获得当前 ...
- CoreGpaphics
CoreGpaphics基本应用 CGAffineTransformMake开头的函数 是基于最初始的位置来变化的 带有CGAffineTransform参数是基于CGAffineTransform的 ...
- BZOJ[4127] Abs
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4127 不算难的样子,才见过此类模型. 首先可以发现每次修改只增不减,那么这$O(n)$的负数最 ...