线程安全异步改装请求



我已经为这个问题挣扎了几个星期。我正在使用改装2.0将地理位置点发布到服务器。我正在使用IntentService,当我有新的点要发布时,我会不时调用它。

出于某种原因,服务器多次记录同一点,创建重复的LOTS。看起来,当我调用我的服务并且它已经处于活动状态时,它将查询点,并使用与前一个请求查询的点相同的点启动新请求。只有当请求成功时,我才会删除该点。有没有办法等到执行下一批点?

如何等到所有处理的点都发送到服务器?

private String postAmazonPoints() throws IOException, JSONException {
    ArrayList<EntityPoint> points = new ArrayList<>(GenericDAO.getInstance(EntityPoint.class).queryForAll());
    if (points.size() == 0) {
        return RESULT_OK;
    }
    if (connectAmazonApi()) {
        int pointSize = points.size();
        if(pointSize>5){
            for(int i = 0; i<pointSize; i+=5){
                int end = i+5;
                if( end > pointSize ){
                    end = pointSize;
                }
                paginatePostPoint(points.subList(i, end-1));
            }
        }else{
            paginatePostPoint(points.subList(0, pointSize-1));
        }
    }
    return RESULT_OK;
}
private void paginatePostPoint(final List<EntityPoint> points) throws IOException, JSONException {
    EntityPoints mPoints = new EntityPoints(points);
    Call<ResponseBody> call = amazonServices.postGeopoints(mPoints);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.isSuccessful()) {
                JSONObject json;
                try {
                    json = (response != null ? new JSONObject(response.body().string()) : null);
                    Log.e(TAG, json.toString());
                    if(RESULT_OK.equals(handleJsonRequest(json))){
                        deleteDatabasePoints(points);
                        Log.e(TAG, "Point are correctly posted");
                    }else{
                        addFirebaseMsg(json.toString());
                    }
                } catch (JSONException e) {
                    Log.e(TAG, e.getLocalizedMessage());
                } catch (IOException e) {
                    Log.e(TAG, e.getLocalizedMessage());
                }
            } else {
                try {
                    addFirebaseMsg(response.errorBody().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            addFirebaseMsg(t.getMessage());
        }
    });
}
private void addFirebaseMsg(String message){
    isConnectedToAmz = false;
    Bundle params = new Bundle();
    params.putString(FirebaseAnalytics.Param.VALUE, message.substring(0, Math.min(message.length(), 30)));
    mFirebaseAnalytics.logEvent(Constants.EVENT_TAG_ERROR, params);
    Log.d(TAG, message);
}

private boolean connectAmazonApi() {
    if (isConnectedToAmz) {
        return true;
    }
    Call<ResponseBody> call = amazonServices.postAuthenticate(settings.getString("token", ""),settings.getString(MyInstanceIDFireService.FIREBASE_TOKEN, ""), settings.getString("id", ""));
    String errMsg = "";
    try {
        ResponseBody response = call.execute().body();
        JSONObject json = (response != null ? new JSONObject(response.string()) : null);
        if (json != null) {
            Log.e(TAG, "Response: " + json.toString());
            RetrofitCreator.setAmazonToken(json.getString("token"));
            isConnectedToAmz = true;
            return true;
        }
        Log.w(TAG, "Impossible to connect to Amazon API : " + json);
    } catch (JSONException e) {
        errMsg = e.getMessage();
    } catch (IOException e) {
        errMsg = e.getMessage();
    }
    Log.w(TAG, "Impossible to connect to Amazon API");
    Bundle params = new Bundle();
    params.putLong(FirebaseAnalytics.Param.VALUE, 1);
    params.putString(FirebaseAnalytics.Param.VALUE, errMsg.substring(0, Math.min(errMsg.length(), 30)));
    mFirebaseAnalytics.logEvent(Constants.EVENT_AMAZON_UNAVAILABLE, params);
    return false;
}

您可以使用.execute而不是.enqueue,请求将是同步的,但在这种情况下,您应该关心为它创建另一个线程。使用asynсtask创建一些服务,例如使用queue。

最新更新