Andrew
Andrew

Reputation: 3

Using RxAndroid with retrofit

I was looking for my question and can't found a solution to my problem, because RxAndroid is hard for me to understand.

How can I get data from Internet and show them on my screen?

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

}

Upvotes: 0

Views: 323

Answers (1)

Gaurav Vashisth
Gaurav Vashisth

Reputation: 7737

Update your method. useRxJava()

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

Some other suggestions and comments:

  1. Use rxjava2 instead of RxJava 1
  2. Make JokeRetrofitInterface a singleton
  3. Retrofit can itself return an Observable, so your JokeRetrofitInterface.getJokes can itself return an Observable (or Single in RxJava 2), it will decrease some amount of code.
  4. I don't find use of RxAndroid in your code, its just plain RxJava
  5. Don't stop learning :). It will hard at first but you will champion it eventually.

Upvotes: 0

Related Questions