1. 程式人生 > >Rxjava+Retrofit 觀察者模式 請求網路資料簡單使用

Rxjava+Retrofit 觀察者模式 請求網路資料簡單使用

首先引入依賴

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

在寫一個介面RetrofitService

//@get 加註解  被觀察者observable 選io包的 泛型 responsebody get 括號里加註解網址和查詢集合map
@GET
Observable<ResponseBody> get(@Url String url, @QueryMap Map<String,String> map);

@POST
Observable<ResponseBody> post(@Url String url, @QueryMap Map<String,String> map);

在寫工具類RetrofitUtils 省略了必須初始化方法更簡便

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

public class RetrofitUtils {

private final RetrofitService retrofitService;
private RetrofitListener retrofitListener;

//本類的構造方法

public RetrofitUtils() {
    //new retrofit 返回值 在builder.新增call 介面卡工廠括號裡傳 Rxjava 2工廠 初始化 .baseurl 傳域名.build提交
    Retrofit retrofit = new Retrofit.Builder()
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl("域名")
            .build();
    //用retrofit呼叫初始化  傳介面 返回值 提上去
     retrofitService = retrofit.create(RetrofitService.class);
}

//公共的get 方法傳呼叫介面的引數
public RetrofitUtils get(String url, Map<String,String> map){
    //先判斷集合為空
    if(map==null){
        //map=new hasmap 泛型為空
        map=new HashMap<>();
    }

    //呼叫提上去的介面 .get 傳兩個引數.subscribeon 傳大寫schedulers.io .subscribeon傳安卓schedulers.mainthresd
    //.subscribe 傳下面封裝的觀察者
    retrofitService
            .get(url,map)
            .subscribeOn(Schedulers.io())
            .subscribeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);

    //記得返回this
    return this;
}

//post 複製get 方法 改兩個post
//公共的get 方法傳呼叫介面的引數
public RetrofitUtils post(String url, Map<String,String> map){
    //先判斷集合為空
    if(map==null){
        //map=new hasmap 泛型為空
        map=new HashMap<>();
    }

    //呼叫提上去的介面 .get 傳兩個引數.subscribeon 傳大寫schedulers.io .subscribeon傳安卓schedulers.mainthresd
    //.subscribe 傳下面封裝的觀察者
    retrofitService
            .post(url,map)
            .subscribeOn(Schedulers.io())
            .subscribeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);

    //記得返回this
    return this;
}


//封裝觀察者 observer 記住io包 new  泛型 responsebody 實現四個方法
private Observer observer=new Observer<ResponseBody>(){

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(ResponseBody responseBody) {
        //成功方法
        //把傳進來的responsebody .小寫字串 先抓異常 後返回值
        try {
            String s = responseBody.string();
            //去下面定義介面
            //呼叫介面的成功方法 傳字串
            retrofitListener.success(s);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onError(Throwable e) {
        //失敗方法
        //把傳進來的e.獲取資訊 返回值
        String message = e.getMessage();
        //呼叫介面失敗方法傳字串
        retrofitListener.fail(message);

    }

    @Override
    public void onComplete() {

    }
};

//介面回撥方法
public void result(RetrofitListener retrofitListener){
    //介面返回值 this. 提上去
     this.retrofitListener = retrofitListener;
}

//定義介面
public interface RetrofitListener{
    //定義成功方法傳字串
    void success(String s);
    //定義失敗方法傳字串
    void fail(String message);
}
}

最後在主頁面呼叫工具類

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

private String url1="域名後面的網址";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //直接new 工具類 呼叫
    new RetrofitUtils().get(url1,null).result(new RetrofitUtils.RetrofitListener() {
        @Override
        public void success(String s) {
            //子執行緒不能更新UI 不能吐司 否則會報錯
            //列印log
            Log.d("MainActivity","請求網路成功"+s);
        }

        @Override
        public void fail(String message) {
            //子執行緒不能更新UI 不能吐司 否則會報錯
            //列印log
            Log.d("MainActivity","請求網路失敗");
        }
    });
}
}