-1

I am downloading JSON Content from server in the MainActivity and passing the JSON from MainActivity to ListActivity, the problem here is I have added a sleep time of 10s in the backend server i.e. Php from where the data is fetched. Since, the response will the delayed I would expect that screen opens and waits until the response comes and move to next screen. But what is happening is the screen goes white/black completely untill the response is recieved and ListActivity is loaded, the problem here is the MainActivity is never visible. Below is code for the same:

MainActivity

JSONData jsonData = new JSONData();
String jsonList = jsonData.fetchList();

Intent intent = new Intent(getApplicationContext(),ListActivity.class);
intent.putExtra("jsonList",jsonList);
startActivity(intent);
finish();

JSON Data class

public String fetchList() {
        try {
            String list = new DownloadJSONData().execute(listURL).get().toString();
            return list;
        } catch (Exception e) {
            return "";
        }
    }

private class DownloadJSONData extends AsyncTask<String, String, String> {
        protected void onPreExecute() {
            super.onPreExecute();
        }

        protected String doInBackground(String... params) {

            HttpURLConnection connection = null;
            BufferedReader reader = null;
            try {
                URL url = new URL(params[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                InputStream stream = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(stream));
                StringBuffer buffer = new StringBuffer();
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line + "\n");
                }
                return buffer.toString();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return "";
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
        }
    }
Abhishek
  • 1,008
  • 1
  • 16
  • 39
  • Here is a hint `.get()`! – Enzokie Aug 18 '18 at 09:18
  • If i Don't use `.get()` then I have to replicate DownloadTask in every activity in order to do actions specific to that activity, since for downloading same code will be used how can I follow the DRY principle as well as not use `.get()`. I need different PostExecute hook on different activity – Abhishek Aug 18 '18 at 09:19
  • Yes I can do that for doing that i need to copy the download task class in every activity, which is not good as well. – Abhishek Aug 18 '18 at 09:23
  • I am not sure if you know this but it is not possible to pass a large string in an Intent, I would say you need to rethink how you design your app. I would prefer if you move your Async code to the `ListActivity`, using it inside in your MainActivity just adds a lot of work in my opinion. – Enzokie Aug 18 '18 at 09:26
  • @Enzokie I agree to the fact intent are not meant for passing large string, but my use case is such that i will always have string of less than 100 char. However since you're saying that I should use Async code in ListActivity that seems to be one solution but if I go to ListDetailActivity there again I need the Async code to download JSON. So, I need to replicate the Async Block in both the activity what will differ is the code present in PostExecute hook. – Abhishek Aug 18 '18 at 09:30
  • I am still confused why you need to replicate it but you might want to try [WorkManager](https://developer.android.com/reference/androidx/work/WorkManager) as alternative to your existing AsyncTask code! See also [LiveData](https://developer.android.com/topic/libraries/architecture/livedata). – Enzokie Aug 18 '18 at 09:36

1 Answers1

2

you are using get() method which accquires the main thread or ui thread untill the async task is completed

you should avoid using get() and also can use progress dialog in onPreExecute for displaying progression on network call to user

Emdad Hossain
  • 387
  • 1
  • 3
  • 10
  • If i Don't use .get() then I have to replicate DownloadTask in every activity in order to do actions specific to that activity, since for downloading same code will be used how can I follow the DRY principle as well as not use .get(). I need different PostExecute hook on different activity. – Abhishek Aug 18 '18 at 09:23
  • for that you can overload methods in AsyncTask for passing different context from different activites and also define a separate class for AsyncTask to reference from all the activities that need the asynctask. – Emdad Hossain Aug 18 '18 at 09:30
  • Can I have a sample for this above statement, I am completely new to Android & Java. Any help would be appreciated. – Abhishek Aug 18 '18 at 09:32