使用 RxAndroid 进行改造

Using RxAndroid with retrofit

我一直在寻找我的问题,但找不到问题的解决方案,因为 RxAndroid 对我来说很难理解。

如何从 Internet 获取数据并将其显示在我的屏幕上?

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

Button btnLoad;
ListView listView;
public static final String BASE_URL = "http://api.icndb.com/";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnLoad = findViewById(R.id.btnSet);
    btnLoad.setOnClickListener(this);
    listView = findViewById(R.id.listView);
}

@Override
public void onClick(View v) {
    useRxJava();
}

private void setAdapter(ArrayList<String> jokes) {
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, jokes);
    listView.setAdapter(adapter);
}

private ArrayList<String> sentRequest() {
    ArrayList<String> jokes = new ArrayList<>();
    Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.build();
    JokeRetrofitInterface client = retrofit.create(JokeRetrofitInterface.class);

    Call<RootObject> call = client.getJokes();
    RootObject rootObject = null;
    try {
        rootObject = call.execute().body();
    } catch (IOException e) {
        e.printStackTrace();
    }
    Value[] values = rootObject.getValue();
    for (Value value : values) {
        String joke = value.getJoke();
        jokes.add(joke);
    }
    return jokes;
}


private void useRxJava() {

    Observable observable = Observable.create(new ObservableOnSubscribe<ArrayList<String>>() {
        @Override
        public void subscribe(ObservableEmitter<ArrayList<String>> emitter) throws Exception {

            ArrayList<String> myJokes = new ArrayList<>();
            myJokes = sentRequest();
            emitter.onNext(myJokes);
        }
    });

    observable.subscribe(new Consumer<ArrayList<String>>() {
        @Override
        public void accept(ArrayList<String> jokes) throws Exception {
            setAdapter(jokes);
        }
    });
}

}

更新你的方法。使用 RxJava()

private void useRxJava() {

    Observable observable = Observable.fromCallable(new 
        Callable<ArrayList<String>>() {
            @Override
            public ArrayList<String> call() throws Exception {
                return sentRequest()
            }
    });

    observable.subscribeOn(Schedulers.io) // This makes sure that network operation happens in io thread
        .observeOn(AndroidSchedulers.mainThread()) // This makes sure that you get response back in main thread
        .subscribe(new Consumer<ArrayList<String>>() {
            @Override
            public void accept(ArrayList<String> jokes) throws Exception {
                setAdapter(jokes);
            }
    });
}

其他一些建议和意见:

  1. 使用 rxjava2 而不是 RxJava 1
  2. 将 JokeRetrofitInterface 设为单例
  3. Retrofit 本身可以 return 一个 Observable,所以你的 JokeRetrofitInterface.getJokes 本身可以 return 一个 Observable(或 RxJava 2 中的 Single),它会减少一些代码量。
  4. 我在你的代码中没有发现 RxAndroid 的使用,它只是普通的 RxJava
  5. 不要停止学习:)。一开始会很难,但你最终会赢得它。