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

Android中如何复用Retrofit代码?请求方法抽离复用方案问询

Absolutely! You can totally extract that repetitive network call logic into a separate class to reuse it across all your Activities. This not only eliminates duplicate code but also keeps your Activities focused on UI-related tasks (following the Single Responsibility Principle). Here are two practical approaches tailored to your current Retrofit setup:

1. Basic Approach: Repository Pattern with Custom Callback

First, let's clean up your original LeafAPI interface by moving the Retrofit/OkHttpClient initialization out of the interface (placing static instances directly in an interface isn't ideal practice):

public interface LeafAPI {
    @GET("someController/serviceName")
    Call<ArrayList<UserDetails>> getUserList();
}

Next, create a dedicated ApiClient class to handle Retrofit instance creation (this centralizes configuration and makes it easy to update later):

public class ApiClient {
    private static Retrofit retrofit = null;
    private static OkHttpClient okHttpClient;

    // Reusable OkHttpClient with logging and timeouts
    private static OkHttpClient getOkHttpClient() {
        if (okHttpClient == null) {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC);
            okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(logging)
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .build();
        }
        return okHttpClient;
    }

    // Get the main Retrofit instance
    public static Retrofit getRetrofitInstance() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(ConstantValues.BaseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .build();
        }
        return retrofit;
    }

    // Optional: Get the scalar-enabled Retrofit instance if you need it
    public static Retrofit getRetrofitScrInstance() {
        return new Retrofit.Builder()
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(ConstantValues.BaseUrl)
                .client(getOkHttpClient())
                .build();
    }
}

Create a custom callback interface to pass results back to your Activities:

public interface UserCallback {
    void onUserListSuccess(ArrayList<UserDetails> userList);
    void onUserListFailure(String errorMessage);
}

Now, build a UserRepository class to encapsulate all user-related network logic:

public class UserRepository {
    private LeafAPI leafAPI;

    public UserRepository() {
        leafAPI = ApiClient.getRetrofitInstance().create(LeafAPI.class);
    }

    // Reusable method to fetch user list
    public void fetchUserList(final UserCallback callback) {
        Call<ArrayList<UserDetails>> call = leafAPI.getUserList();
        call.enqueue(new Callback<ArrayList<UserDetails>>() {
            @Override
            public void onResponse(Call<ArrayList<UserDetails>> call, retrofit2.Response<ArrayList<UserDetails>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    callback.onUserListSuccess(response.body());
                } else {
                    callback.onUserListFailure("Failed to load users: " + response.message());
                }
            }

            @Override
            public void onFailure(Call<ArrayList<UserDetails>> call, Throwable t) {
                callback.onUserListFailure("Network error: " + t.getMessage());
            }
        });
    }
}

Usage in Any Activity

Now you can reuse this logic in any Activity with just a few lines:

private void getUserDetails() {
    UserRepository userRepo = new UserRepository();
    userRepo.fetchUserList(new UserCallback() {
        @Override
        public void onUserListSuccess(ArrayList<UserDetails> userList) {
            // Process and display user list in your UI
        }

        @Override
        public void onUserListFailure(String errorMessage) {
            // Show error message to the user
        }
    });
}

2. Advanced Approach: ViewModel + LiveData (Jetpack)

If you're using Android Jetpack, this approach is even better—it avoids memory leaks (since ViewModels survive configuration changes) and keeps your UI code cleaner.

First, create a UserViewModel that holds the data state:

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class UserViewModel extends ViewModel {
    private final MutableLiveData<ArrayList<UserDetails>> userListLiveData = new MutableLiveData<>();
    private final MutableLiveData<String> errorLiveData = new MutableLiveData<>();
    private final UserRepository userRepository;

    public UserViewModel() {
        userRepository = new UserRepository();
    }

    public void fetchUserList() {
        userRepository.fetchUserList(new UserCallback() {
            @Override
            public void onUserListSuccess(ArrayList<UserDetails> userList) {
                userListLiveData.postValue(userList); // Update data on main thread
            }

            @Override
            public void onUserListFailure(String errorMessage) {
                errorLiveData.postValue(errorMessage);
            }
        });
    }

    // Expose immutable LiveData to the UI
    public LiveData<ArrayList<UserDetails>> getUserListLiveData() {
        return userListLiveData;
    }

    public LiveData<String> getErrorLiveData() {
        return errorLiveData;
    }
}

Usage in Activity

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

public class YourActivity extends AppCompatActivity {
    private UserViewModel userViewModel;

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

        // Initialize ViewModel
        userViewModel = new ViewModelProvider(this).get(UserViewModel.class);

        // Observe user list updates
        userViewModel.getUserListLiveData().observe(this, userList -> {
            // Update UI with user list
        });

        // Observe errors
        userViewModel.getErrorLiveData().observe(this, errorMessage -> {
            // Show error to user
        });

        // Trigger the network request
        userViewModel.fetchUserList();
    }
}

Both approaches eliminate duplicate code across Activities. The basic repository pattern works great for simple apps, while the ViewModel approach is ideal for apps that need to handle configuration changes (like screen rotations) gracefully.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:50:49