0

How to prevent the data being loaded again when coming from another intent. For instance, I have a MainActivity where I'm making GET call to APIs in onCreate() method. I click on one of the cards and it fires an another activity called CardActivity.

When I hit back from this CardActivity, the data is being loaded again. I tried onPause() method as well but not luck. How do I prevent the data which is being loaded when navigating between Activities.

Could anyone please guide me how to achieve this?

I'm using Volley library for making HTTP calls.

@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);
    }
coderpc
  • 4,119
  • 6
  • 51
  • 93

3 Answers3

1

There are many possible answers to this question. You can store the data locally in an SQLite database and then can read the data from there when needed. If your data is likely to be changed frequently, then it is not a good idea. You might consider using the caching system that comes with the Volley. To see how the caching will Volley can be implemented you can refer to this link.

Another way of doing it is by passing the data between your activities as objects. If the data is not likely to be changed during the activity transition, this is a good idea in my opinion. In this way, you do not load the data each time from the network. So once the data is read in the MainActivity, it can be passed to the CardActivity as an object or an intent.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
0

You can consider setting your MainActivity as a SingleTop launch mode, and then let CardActivity start MainActivity via intent when the back button is pressed.

this will cause onNewIntent() to be called instead of 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.

Angel Koh
  • 12,479
  • 7
  • 64
  • 91
  • note that onNewIntent() will retain your current data if it's already loaded. if MainActivity got destroyed during CardActivity's phase, then onCreate will be called again (and it will hit the Volley for data again). - if that is not what you want, then you will need to implement some sort of persistency of your local data (sqlite, sharedPreferences, etc) – Angel Koh Oct 11 '19 at 01:12
0

Here's what I tried based on @Reaz Murshed suggestion. This article on Medium helped me to implement the Cache approach.

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

Hoping this would help someone

coderpc
  • 4,119
  • 6
  • 51
  • 93