0

I have created an android application which gets some data from google place api. It returns a Json object in AsyncTask. Then I put every record into list of object and on that list I do some operation which needs data from DB. Because it is simple app I use JDBC to connect to database. When I do some operation on above list my UI blocks for long time. The methods looks like:

private void generateMap(LatLng latLng, String distance) {
        List<WashLocation> list = new ArrayList<>();

        MyAsyncTask myAsyncTask = new MyAsyncTask();

        try {
            JSONObject jsonObject = myAsyncTask.execute(latitude, longitude, radius).get();
            String lat;
            String lng;
            String name = "";
            String city = "";
            String placeId = "";
            if (jsonObject != null) {
                if (jsonObject.has("results")) {
                    JSONArray jsonArray = jsonObject.getJSONArray("results");
                    for (int n = 0; n < jsonArray.length(); n++) {
                        JSONObject jsonObject1 = jsonArray.getJSONObject(n);
                        lat = jsonObject1.getJSONObject("geometry").getJSONObject("location").get("lat").toString();
                        lng = jsonObject1.getJSONObject("geometry").getJSONObject("location").get("lng").toString();

                        JSONObject oName = jsonArray.getJSONObject(n);
                        if (oName.has("name")) {
                            name = oName.getString("name");
                        }

                        JSONObject oVicinity = jsonArray.getJSONObject(n);
                        if (oVicinity.has("vicinity")) {
                            city = oVicinity.getString("vicinity");
                        }
                        JSONObject oPlaceId = jsonArray.getJSONObject(n);
                        if (oPlaceId.has("place_id")) {
                            placeId = oPlaceId.getString("place_id");
                        }
                        WashLocation w = new WashLocation(name, lat, lng, 0, getCity(city), null, placeId);
                        list.add(w);
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
       for(WashLocation washLocation: list) {
       try {
           WashLocation washLocation1 = new CheckPlaceID(washLocation).execute().get();
           washLocations.add(washLocation1);
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }
   }
    }

Inner class:

private class CheckPlaceID extends AsyncTask<Void, Void, WashLocation> {
        private WashLocation washLocation;
        String placeId;

        public CheckPlaceID(WashLocation washLocation) {
            this.washLocation = washLocation;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected void onPostExecute(WashLocation washLocation) {
            super.onPostExecute(washLocation);
        }

        @Override
        protected WashLocation doInBackground(Void... params) {
            DataBaseHelperRemote dataBaseHelperRemote = new DataBaseHelperRemote();
            List<WashLocationRemoteDB> allWashLocationFromRemoteDB = dataBaseHelperRemote.getAllWashLocationFromRemoteDB(); //data from DB
            WashLocationRemoteDB washLocationRemoteDBByPlaceId = dataBaseHelperRemote.getWashLocationRemoteDBByPlaceId(washLocation.getPlaceId()); //data from DB
            if(washLocation != null){
                if(washLocationRemoteDBByPlaceId != null){
                    if(allWashLocationFromRemoteDB != null){
                        for(WashLocationRemoteDB db : allWashLocationFromRemoteDB){
                            if(db.getPlaceId().equalsIgnoreCase(washLocation.getPlaceId())){
                                washLocation.setWashName("tu coś jest!");
                                break;
                            }
                        }
                    }
                }
            }
            return washLocation;
        }

How can I improve the speed of that process and to not bocking the UI?

bielas
  • 672
  • 2
  • 12
  • 29
  • I believe your blocking problem is due to you using `.get` on your async tasks. Normally the result should be passed back in a callback. I would probably include the JSON parsing part in the background part of the async task and try to reduce it to one callback. – Adam Forbis May 15 '17 at 19:45
  • @AdamForbis so how can I get the result by not using `.get`? – bielas May 15 '17 at 19:56
  • 2
    Possible duplicate of [Properly Using AsyncTask get()](http://stackoverflow.com/questions/16007137/properly-using-asynctask-get) – Veneet Reddy May 15 '17 at 20:02
  • Look at the @VeneetReddy link, Use an interface, I will be off work in a couple hours and give you an actual answer if you can't figure it out by then. – Adam Forbis May 15 '17 at 20:48

1 Answers1

1

When working with asynchronous android code, you normally use interface callbacks. You want to do operations as the result of an operation on the other thread. Never wait on another thread from the UI thread, you will block it.

An interface example:

/*So an interface like this */
public interface WashLocationInterface{
    public void onWashLocationRetrieved(WashLocation location);
}

The AsyncTask:

/*Can be used like */
private class CheckPlaceID extends AsyncTask<Void, Void, WashLocation> {
        /* Not showing variables*/

        public CheckPlaceID(WashLocation washLocation, WashLocationInterface washLocationInterface) {
            this.washLocation = washLocation;
            /*We can pass in an implementation of this interface to the async task*/
            this.washLocationInterface = washLocationInterface;
        }
        /* Not showing on pre execute*/
        @Override
        protected void onPostExecute(WashLocation washLocation) {
            super.onPostExecute(washLocation);
            /* We call the method in the interface here,
            this will then be called in the implementation in the interface*/
            washLocationInterface.onWashLocationRetrieved(washLocation);
        }

        @Override
        protected WashLocation doInBackground(Void... params) {
           /* Not showing code for brevity*/
           /* long running work*/
            return washLocation;
        }
}

An example method:

/* Example interface implementation, if */
public exampleMethod(){/* Could be some lifecycle method like onCreate*/
    /* This interface only needs created once*/
    WashLocationInterface washLocationInterface = new WashLocationInterface(){
        @Override
        public void onWashLocationRetrieved(WashLocation location){
            /* Maybe update ui in here, or call some method that needs to be called when 
            data is retrieved*/
        }
    }
    /* Pass the interface into the async task, which then can call the method*/
    new CheckPlaceID(/* Some existing wash location */washLocation, washLocationInterface).execute();
}
Adam Forbis
  • 461
  • 3
  • 11
  • Thanks for that post. I will check it when I get home. BTW. Yesterday I did some workaround if we talk about AsyncTask and when I test it through the phone which was plugged into computer- everything works, but with some delay. However when I ran the same application on the phone which wasn't plugged today, application doesn't work. Do you know (of course in general now) what could be the reason of that kind of behavior? – bielas May 16 '17 at 13:36
  • The funny thing is that I haven't changed anything since I test it last time and now it works... – bielas May 16 '17 at 13:41
  • @bielas It could be any number of things, the first thing I would do is check my stack traces. It could be in a difference in network speed, cpu it can use do to power saving features, server glitching out. Normally stack traces will tell you why though. – Adam Forbis May 16 '17 at 13:43