应用中如何维护API数据 避免重复GET请求及SPLASH实现方案咨询
临时全局数据的正确存储方式
根据你需要的缓存生命周期可以选择两种方案:
- 仅本次启动生效:使用自定义Application类或者线程安全的单例类做内存级存储,开销最低,读写速度最快,符合你避免重复请求的需求
- 跨启动生效:如果数据允许一定时效内复用,不需要每次启动都重新请求,可以使用
SharedPreferences(存储轻量级键值对)、Room数据库(存储结构化批量数据)做持久化存储,配合时间戳做过期校验即可
Splash页预请求存储方案的具体实现
1. 先定义全局数据持有载体
这里以自定义Application为例,稳定性高于普通单例,不会出现意外的内存回收问题:
首先创建自定义Application类:
// 注意这里的ApiResponseData是你自己定义的接口返回数据的结构化实体类 public class MyApp extends Application { // 全局持有接口返回的数据 private ApiResponseData apiData; public void setApiData(ApiResponseData apiData) { this.apiData = apiData; } public ApiResponseData getApiData() { return apiData; } }
然后在AndroidManifest.xml的application标签中注册这个自定义类:
<application android:name=".MyApp" <!-- 其余原有配置保持不变 --> > <!-- Activity等组件配置 --> </application>
2. 在Splash Activity中实现请求与存储逻辑
Splash页的核心逻辑是:优先判断是否有可用缓存,没有再发起请求,请求完成后再跳转主页:
public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); // 如果做了持久化缓存,先校验本地缓存是否在有效期内,有效则直接跳转 // 无缓存则发起网络请求 OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("你的自有API接口地址") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { // 这里可以加重试逻辑,或者提示用户网络异常后退出应用 runOnUiThread(() -> Toast.makeText(SplashActivity.this, "网络异常,请稍后重试", Toast.LENGTH_SHORT).show()); } @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { if (response.isSuccessful() && response.body() != null) { // 把返回的JSON解析成你定义的ApiResponseData实体类 ApiResponseData data = new Gson().fromJson(response.body().string(), ApiResponseData.class); // 存入全局Application ((MyApp) getApplication()).setApiData(data); // 如果需要持久化,这里可以同时把数据写入SharedPreferences/Room,同时记录缓存时间戳 // 跳转到主页面 runOnUiThread(() -> { startActivity(new Intent(SplashActivity.this, MainActivity.class)); finish(); }); } } }); } }
3. 其他Activity调用存储的数据
所有需要用到接口数据的页面,直接从全局Application中读取即可,不需要再发起请求:
// 任意Activity中调用 ApiResponseData data = ((MyApp) getApplication()).getApiData(); // 直接使用data中的字段即可
注意事项
- 如果数据体积较大,不要全量存在内存中,建议仅缓存高频使用的字段,其余数据做本地持久化按需读取
- 如果数据有更新要求,建议在缓存时同步存储时间戳,每次应用切到前台时校验有效期,过期则自动重新拉取数据
- 不要在全局存储的ApiResponseData中持有任何Activity的Context引用,避免引发内存泄漏
内容的提问来源于stack exchange,提问作者Fumatamax
相关产品推荐
相关产品推荐

