在活动之间导航时如何在不加载数据的情况下保留数据

How to preserve the data without it being loaded when navigated between Activities

如何防止来自另一个意图的数据被再次加载。例如,我有一个 MainActivity,我在其中对 onCreate() 方法中的 API 进行 GET 调用。我单击其中一张卡片,它会触发另一张名为 CardActivity 的 activity。

当我从这个 CardActivity 回击时,正在再次加载数据。我也尝试了 onPause() 方法,但运气不好。如何防止在活动之间导航时加载的数据。

谁能指导我如何实现这一点?

我正在使用 Volley 库进行 HTTP 调用。

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

        requestQueue = MySingleton.getInstance(this.getApplicationContext()).getRequestQueue();

        getRedditDefaultData();
        getGoogleHeadlinesData();

    }

    private void getRedditDefaultData() {

        final String url = "https://example.com"

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                                ...
                                dataset.add(new StaggeredCustomCard(
                                        redditUserProfilePic,
                                        redditUserName,
                                        redditPostDateTime,
                                        redditPostTitle,
                                        null,
                                        redditPostDescription));
                            }
                            if (dataset != null) {
                              staggeredGridAdapter.notifyDataSetChanged();
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO: Handle error
                        progressBar.setVisibility(View.GONE);
                    }
                });
        retryPolicy(jsonObjectRequest);
       MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
    }

这个问题有很多可能的答案。您可以将数据本地存储在 SQLite 数据库中,然后可以在需要时从那里读取数据。如果您的数据可能会经常更改,那么这不是一个好主意。您可以考虑使用 Volley 附带的缓存系统。要了解 Volley 的缓存是如何实现的,您可以参考

另一种方法是将数据作为对象在活动之间传递。如果在 activity 转换期间数据不太可能更改,我认为这是个好主意。这样,您就不会每次都从网络加载数据。因此,一旦在 MainActivity 中读取数据,就可以将其作为对象或意图传递给 CardActivity

你可以考虑将你的MainActivity设置为SingleTop启动模式,然后让CardActivity在按下后退按钮时通过intent启动MainActivity。

这将导致调用 onNewIntent() 而不是 onCreate()。

https://developer.android.com/reference/android/app/Activity.html#onNewIntent(android.content.Intent)

onNewIntent

Added in API level 1

protected void onNewIntent (Intent intent)

This is called for activities that set launchMode to "singleTop" in their package, or if a client used the Intent#FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.

An activity can never receive a new intent in the resumed state. You can count on onResume() being called after this method, though not necessarily immediately after the completion this callback. If the activity was resumed, it will be paused and new intent will be delivered, followed by onResume(). If the activity wasn't in the resumed state, then new intent can be delivered immediately, with onResume() called sometime later when activity becomes active again.

Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.

这是我根据@Reaz Murshed 的建议尝试的。 Medium 上的这个 article 帮助我实现了缓存方法。

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        ...

                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        ...
                    }
                }) {
            @Override
            protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
                try {
                    Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
                    if (cacheEntry == null) {
                        cacheEntry = new Cache.Entry();
                    }
                    final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
                    final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
                    long now = System.currentTimeMillis();
                    final long softExpire = now + cacheHitButRefreshed;
                    final long ttl = now + cacheExpired;
                    cacheEntry.data = response.data;
                    cacheEntry.softTtl = softExpire;
                    cacheEntry.ttl = ttl;
                    String headerValue;
                    headerValue = response.headers.get("Date");
                    if (headerValue != null) {
                        cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
                    }
                    headerValue = response.headers.get("Last-Modified");
                    if (headerValue != null) {
                        cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
                    }
                    cacheEntry.responseHeaders = response.headers;
                    final String jsonString = new String(response.data,
                            HttpHeaderParser.parseCharset(response.headers));
                    return Response.success(new JSONObject(jsonString), cacheEntry);
                } catch (UnsupportedEncodingException | JSONException e) {
                    return Response.error(new ParseError(e));
                }
            }

            @Override
            protected void deliverResponse(JSONObject response) {
                super.deliverResponse(response);
            }

            @Override
            public void deliverError(VolleyError error) {
                super.deliverError(error);
            }

            @Override
            protected VolleyError parseNetworkError(VolleyError volleyError) {
                return super.parseNetworkError(volleyError);
            }
        };

希望这对某人有所帮助