两个AsyncTasks互相阻塞

时间:2017-05-15 19:32:21

标签: android multithreading android-asynctask

我创建了一个from msvcrt import getch pos = [0, 0] def fright(): global pos pos[0] += 1 def fleft(): global pos pos[0] -= 1 def fup(): global pos pos[1] += 1 def fdown(): global pos pos[1] -= 1 while True: print'Distance from zero: ', pos key = ord(getch()) if key == 27: #ESC break elif key == 13: #Enter print('selected') elif key == 32: #Space print('jump') elif key == 224: #Special keys (arrows, f keys, ins, del, etc.) key = ord(getch()) if key == 80: #Down arrow print('down') fdown elif key == 72: #Up arrow print('up') fup() elif key == 75: #Left arrow print('left') fleft() elif key == 77: #Right arrow print('right') fright() 应用程序,它从android获取一些数据。它会在google place api中返回Json object。然后我将每条记录放入AsyncTask对象中,并在该列表中执行一些需要list数据的操作。由于它是简单的应用,因此我使用DB连接到JDBC。当我在上面的列表上执行某些操作时,我的database会阻塞很长时间。方法如下:

UI

内班:

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

如何提高该流程的速度,而不是阻止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; }

1 个答案:

答案 0 :(得分:1)

使用异步android代码时,通常使用接口回调。您希望在另一个线程上执行操作。永远不要等待UI线程中的另一个线程,你将阻止它。

接口示例:

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

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

示例方法:

/* 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();
}