You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合RxAndroid与Retrofit实现网络数据获取及屏幕展示?

How to Use RxAndroid with Retrofit for Network Data Fetching & UI Display

Let's break down what's wrong with your current implementation and fix it to properly leverage RxAndroid and Retrofit for safe, efficient network calls and UI updates:

Issues in Your Current Code

  • Blocking Network Call on Main Thread: Your sentRequest() uses call.execute() (a synchronous method) and runs it directly in the Observable.create() block, which executes on the main thread by default. This will cause an ANR (Application Not Responding) error because you're blocking the UI thread with network operations.
  • Missing Thread Scheduling: RxJava doesn't automatically handle thread switching. You need to explicitly tell it to run network work on a background thread and deliver results to the main thread for UI updates.
  • No Error Handling: There's no mechanism to catch network failures or parsing errors, which will crash your app if something goes wrong.
  • Redundant Observable Wrapping: Retrofit has built-in support for returning Observables directly—you don't need to manually wrap a synchronous call in an Observable.

Step 1: Add Required Dependencies

First, make sure you have these dependencies in your build.gradle (Module level) to support RxAndroid, Retrofit, and their integration:

implementation 'io.reactivex.rxjava3:rxjava:3.1.5'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'

Step 2: Update Your Retrofit Interface

Modify your JokeRetrofitInterface to return an Observable instead of a Call—this lets Retrofit handle the RxJava integration for you:

public interface JokeRetrofitInterface {
    // Adjust the endpoint to match your actual API (example uses 10 random jokes)
    @GET("jokes/random/10")
    Observable<RootObject> getJokes();
}

Step 3: Fix the MainActivity Implementation

Here's the revised MainActivity code with proper thread scheduling, error handling, and memory leak prevention:

public class MainActivity extends AppCompatActivity implements View.OnClickListener { 
    Button btnLoad; 
    ListView listView; 
    public static final String BASE_URL = "http://api.icndb.com/";
    private Disposable disposable; // Manages subscription to prevent memory leaks

    @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<>(this, android.R.layout.simple_list_item_1, jokes); 
        listView.setAdapter(adapter); 
    } 

    private void useRxJava() { 
        // Build Retrofit instance with RxJava adapter
        Retrofit retrofit = new Retrofit.Builder() 
                .baseUrl(BASE_URL) 
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) // Critical for Rx support
                .build(); 

        JokeRetrofitInterface client = retrofit.create(JokeRetrofitInterface.class); 

        // Execute request with proper thread scheduling
        disposable = client.getJokes()
                .subscribeOn(Schedulers.io()) // Run network call on background IO thread
                .observeOn(AndroidSchedulers.mainThread()) // Deliver results to main thread for UI
                .subscribe(new Observer<RootObject>() { 
                    @Override 
                    public void onSubscribe(@NonNull Disposable d) {
                        // Optional: Show loading spinner here
                    }

                    @Override 
                    public void onNext(@NonNull RootObject rootObject) { 
                        // Parse the response into a list of jokes
                        ArrayList<String> jokes = new ArrayList<>(); 
                        for (Value value : rootObject.getValue()) { 
                            jokes.add(value.getJoke()); 
                        } 
                        setAdapter(jokes); 
                    } 

                    @Override 
                    public void onError(@NonNull Throwable e) { 
                        // Handle errors (e.g., network failure, parsing issues)
                        Toast.makeText(MainActivity.this, "Failed to load jokes: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                        e.printStackTrace(); 
                    } 

                    @Override 
                    public void onComplete() {
                        // Optional: Hide loading spinner here
                    }
                }); 
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Cancel subscription to prevent memory leaks when Activity is destroyed
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}

Key Improvements Explained

  • Thread Scheduling: subscribeOn(Schedulers.io()) ensures the network call runs on a background thread, while observeOn(AndroidSchedulers.mainThread()) makes sure the UI update happens on the main thread (required for modifying views).
  • Error Handling: The onError() method catches any exceptions during the network call or parsing, so your app won't crash unexpectedly.
  • Memory Leak Prevention: The Disposable is disposed in onDestroy() to clean up the subscription when the Activity is no longer active.
  • Cleaner Retrofit Integration: Using Retrofit's built-in Rx adapter eliminates the need for manual Observable creation and synchronous calls.

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:39:48