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();
}
}

最新文章

  1. hadoop2.2.0伪分布式搭建3--安装Hadoop
  2. MMORPG大型游戏设计与开发(服务器 AI 概述)
  3. C#常用操作类库四(File操作类)
  4. Windows下查看JDK是否安装以及安装路径
  5. Quartz2D复习(二) --- 手势解锁
  6. 枚举型Enum和结构型Stuct
  7. phpstudy配置ssl
  8. 安装java和jmeter
  9. java android ExecutorService 线程池解析
  10. c 递归函数浅析
  11. I.MX6 Android Linux shell MMPF0100 i2c 设置数据
  12. codeforces C. Cd and pwd commands 执行命令行
  13. java 随机生成11位 组合
  14. 服务器性能分析工具gprof的使用及没有生成gmon.out文件的原因
  15. HBase shell 命令介绍
  16. javascript 原型机制
  17. 在阿里云ECS CentOS7上部署基于MongoDB+Node.js的博客
  18. Javascript 3.2
  19. Flask web 开发出现错误:TypeError: Allowed methods have to be iterables of strings, for example: @app.route(..., methods=[&quot;POST&quot;])
  20. 解决&quot;mysql-bin.000001&quot;占用超大空间的问题

热门文章

  1. 【POJ 1159】Palindrome
  2. 传统maven项目创建
  3. javaScript实现增删改查
  4. 关于python代码的性能
  5. 压缩&amp;&amp;解压
  6. (bmp格式)用CDialog的OnCtlColor()消息响应处理背景画刷。
  7. windows cmd下如何暂停(挂起)运行中的进程
  8. 3DMAX 9 角色建模3 uv展开
  9. 关于 &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;的解释
  10. Tasks 多核查找最大最小值问题