Rxjava+retrofit2+OKHttp+GSON实践

Rxjava+retrofit2+OKHttp+GSON实践(新浪微博API调用实例)


网络请求

建议学习了以下知识才看这篇文章:
OKHTTP3请参考:http://blog.csdn.net/weixin_37577039/article/details/78546444
retrofit2 请参考:http://blog.csdn.net/weixin_37577039/article/details/78546591
JSON解析:http://blog.csdn.net/weixin_37577039/article/details/78546482
新浪微博JSON解析实践:http://blog.csdn.net/weixin_37577039/article/details/78619940
Rxjava2请参考:http://blog.csdn.net/weixin_37577039/article/details/78555208


1 添加配置文件,添加权限
包一定要导对,这里是个坑

     //retrofit2
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    //Gson converter
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    //RxJava2 Adapter
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    //rxjava2
    compile 'io.reactivex.rxjava2:rxjava:2.1.5'
    //rxandroid2
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    //okhttp
    compile 'com.squareup.okhttp3:okhttp:3.9.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    // 新浪微博SDK
    compile 'com.sina.weibo.sdk:core:4.1.0:openDefaultRelease@aar'

有时候某个Sync不通过就try again试下


AndroidManifest.xml中

<uses-permission android:name="android.permission.INTERNET"/>

当获得了AccessToken后,去调用API接口了 这里就要用Rxjava进行异步操作,上游执行网络请求,下游进行数据处理,UI更新


这里将Observable为< ResponseBody>参数的
其他参数为BEAN类的其实也一样
将ResponseBody部分改为BEAN类即可

@Override
public void onNext(XXBean xxBean) {
// 替换了那个call.enqueue方法 直接在这里进行获取
Log.i("myAccessToken", xxBean.getXXX() );// 即可以得到BEAN类中对应的数据
}
//call对象声明
private io.reactivex.Observable<AccessTokenBean> call_1;

2 定义接口
(retrofit2 负责部分,原retrofit2改call为Observable)

public interface HttpService {
//调用API
@GET("2/statuses/home_timeline.json?")
Observable<ResponseBody> getAPI(@Query("access_token") String accessToken, @Query("count") int count);

}

3 接着创建一个Retrofit客户端
(retrofit2和okhttp3 原retrofit2增加了.addCallAdapterFactory)

private Context mContext;
 public void createRetrofit(String accessToken,Context context){
        mContext=context;
        //OKHttp进行超时设置,拦截器等设置
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        builder.readTimeout(10, TimeUnit.SECONDS);
        builder.connectTimeout(9, TimeUnit.SECONDS);
        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(interceptor);
        }
 // 创建gson实例
    Gson gson = new GsonBuilder()
    //配置你的Gson
    .setDateFormat("yyyy-MM-dd hh:mm:ss")
    .create();
//创建Retrofit实例
    Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(baseUrl)
    .client(builder.build())
    .addConverterFactory(GsonConverterFactory.create(gson))
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build();

4 发送请求

//先声明
private Observable<ResponseBody> call_1;

//用retrofit创建HttpService对象
        final HttpService httpService = retrofit.create(HttpService.class);
         // 接口调用
        call_1= httpService.getAPI(accessToken,COUNT);
        //!!!这里是一个坑!!!
        //这里可能会报错 说retrofit.call不能转化为io.reactivex.observable类型 按ALT+ENTER去选择最后一个,return httpService为io.reactivex.observable格式的(大概这个意思)就OK了

        // RXJAVA实现
        call_1.subscribeOn(Schedulers.io()) //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
                .subscribe(new Observer<ResponseBody>() {
                    @Override
// 连接成功了就会执行
  public void onSubscribe(Disposable d) {
      Log.i("subscribe is ok","subscribe is ok" );
  }
  @Override
  public void onNext(ResponseBody responseBody) {
      Toast.makeText(mContext, "调用API成功", Toast.LENGTH_SHORT).show();
      try {
          str=responseBody.string();
      } catch (IOException e) {
          e.printStackTrace();
      }
      Log.i("str",str);
      //开始解析
      try {
          // 将返回的JSONString格式赋予JSONObject
          JSONObject jsonObject = new JSONObject(str);
          // 第一层为statuses 并且statuses为数组形式 因此将其设置为JSONArray形式
          JSONArray statusesArr = jsonObject.getJSONArray("statuses");
          // 循环地去获得多条微博
          // 这里的index+1代表的是第n条status(微博),因此index=0 为第一条 以此类推
          for (int i = 0; i < COUNT; i++) {
              // 第一条 下标从0开始
              JSONObject statusesObj = statusesArr.getJSONObject(i);
              // statuses中的第一层,即总的第二层
              // 该条微博的创建时间
              created_at[i] = statusesObj.getString("created_at");
              Log.i("created_at", created_at[i]);
              //该条微博的来源
              source[i] = statusesObj.getString("source");
              Log.i("source", source[i]);
              //该条微博的转发数
              reposts_count[i] = statusesObj.getString("reposts_count");
              Log.i("reposts_count", reposts_count[i]);
              //该条微博的评论数
              comments_count[i] = statusesObj.getString("comments_count");
              Log.i("comments_count", comments_count[i]);
              //该条微博的点赞数
              attitudes_count[i] = statusesObj.getString("attitudes_count");
              Log.i("attitudes_count", attitudes_count[i]);
              //该条微博的微博text内容
              text[i] = statusesObj.getString("text");
              Log.i("text", text[i]);
              // 总的第三层
              // 获取user的值
              String user = statusesObj.getString("user");
              //user转化为JSONObject
              JSONObject userObj = new JSONObject(user); // 将其转化为JSONObject
              //微博主名
              screen_name[i] = userObj.getString("screen_name"); // 使用getXX方法获取数据
              Log.i("screen_name", screen_name[i]);
              //微博主照片的地址
              profile_image_url[i] = userObj.getString("profile_image_url"); // 使用getXX方法获取数据
              Log.i("profile_image_url", profile_image_url[i]);
          }
          // 若成功传入最后一个微博 指定一个变量 而不是只是一个数值 因为网络请求要花时间
          if(profile_image_url[COUNT-1]!=null){
              //若有值
              canIntent=true;
              // 非Activity中跳转 满足MVVM吗  不满足要改~~~~~~
              Intent intent = new Intent(mContext, MainActivity.class);
              mContext.startActivity(intent);
          }else{
              canIntent=false;
          }
      } catch(JSONException e){
          e.printStackTrace();
      }
  }
  @Override
  public void onError(Throwable e) {
      Log.i("API调用失败","API调用失败");
      Toast.makeText(mContext, "API调用失败", Toast.LENGTH_SHORT).show();
  }
  //上游不写complete  成功返回也会自动执行
  @Override
  public void onComplete() {
      Log.i("API调用成功","API调用成功");
      Toast.makeText(mContext, "API调用成功", Toast.LENGTH_SHORT).show();
  }
});

思考:
当方法A先执行,但是方法A要去调用监听,他的回调数据还没回调,这时会执行下面的B方法,但是B方法又需要A的回调数据,此时涉及到方法的异步调用问题
可以用RXJava解决这个问题
原理:在回调方法中,用RXJAVA去进行上下游的异步操作

如新浪微博通过OAuth授权方式获取accessToken,回调这个accessToken需要时间,则可以在回调的方法中,Rxjava上游去接受回调,处理回调数据,然后处理完了,再去发送数据给下游,下游有了数据再去利用该数据调用新的请求
(不够好?用FlatMap?见Rxjava(三)系列)
代码示例见Github的SinaWeiBoDemo的LoginActivity中:


很多业务中,需要上一个请求成功了,得到数据并处理了,才进行下一个请求,这里涉及了请求先后顺序的问题
请参考下一篇博客:
Rxjava2(三):http://blog.csdn.net/weixin_37577039/article/details/78622443


但是当请求未完成或刚完成,Activity销毁了,则不应该更新主线程UI了,因此在Activity中将这个Disposable 保存起来, 当Activity退出时, 切断它即可
果有多个Disposable
RxJava中已经内置了一个容器CompositeDisposable, 每当我们得到一个Disposable时就调用CompositeDisposable.add()将它添加到容器中, 在退出的时候, 调用CompositeDisposable.clear() 即可切断所有的水管

Disposable使用参考 RXjava(一):
http://blog.csdn.net/weixin_37577039/article/details/78555208


参考链接:http://www.jianshu.com/p/8818b98c44e2

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值