CountDownLatch 使应用程序停止

CountDownLatch makes the app stop

我正在处理 CountDownLatch,我需要发送两个 JSON 按顺序发送。

我想出了这个

   CountDownLatch countDownLatch = new CountDownLatch(1);
                try {
                    sendAndgetEODID(countDownLatch);
                    countDownLatch.await();
                    sendAndgetDispID();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

sendAndGetEODID 函数的内部是

private void sendAndgetEODID(final CountDownLatch countDownLatch) {

    Log.e("going to EOD", "going to EOD");

    JSONObject params = new JSONObject();

    try {
        params.put("company_id", CompanyID);
        params.put("subcompany_id", subCompID);
        params.put("control_no", control_no);
        params.put("trip_no", trip_no);
        params.put("bus_id", bus_id);
        params.put("conductor_id", conductor_id);
        params.put("driver_id", driver_id);
        params.put("driver2_id", null); //temporary
        params.put("device_serial", dev_serial);
        params.put("datetimestamp", datetimestamp);

        String baseUrl = null;

        final ConnectivityManager connMgr = (ConnectivityManager)
                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        final android.net.NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        final android.net.NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        if (wifi.isConnected()) {
            baseUrl = url1;
        } else if (mobile.isConnected()) {
            baseUrl = url2;
        }

        AndroidNetworking.post(baseUrl + "atts_eods")
                .addJSONObjectBody(params)
                .addHeaders("Content-Type", "application/json")
                .addHeaders("Prefer", "return=representation")
                .addHeaders("Accept", "application/vnd.pgrst.object+json")
                .setPriority(Priority.HIGH)
                .build()
                .getAsJSONObject(new JSONObjectRequestListener() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Log.e("response EOD", String.valueOf(response));

                        try {
                            eod_return_id = String.valueOf(response.get("id"));

                            String queryEOD = ("update " + DBHelper.TRANS_EOD + " set " +
                                    DBHelper.TRANS_EOD_RETURN_ID + " = '" + eod_return_id +
                                    "', is_send = '1' where control_no = '" + control_no + "'");
                            sqldb.execSQL(queryEOD);

                            String updateTransSettingsEODID = ("update " + DBHelper.TRANS_SETTINGS + " set " +
                                    DBHelper.TRANS_EOD_RETURN_ID + " =  '" + eod_return_id +
                                    "' where control_no = '" + control_no + "'");

                            sqldb.execSQL(updateTransSettingsEODID);

                            String updateEODIDDispatch = ("update " + DBHelper.TRANS_DISPATCH + " set " +
                                    DBHelper.TRANS_DISPATCH_EOD_ID + " = '" + eod_return_id +
                                    "' where control_no = '" + control_no + "' and trip_no = '" + trip_no + "' ");

                            sqldb.execSQL(updateEODIDDispatch);


                            EODIDCatcher = eod_return_id;
                            Log.e("EODIDCatcher UP!", EODIDCatcher);

                            countDownLatch.countDown();

                        } catch (JSONException e) {
                            e.printStackTrace();
                            countDownLatch.countDown();
                        }
                    }

                    @Override
                    public void onError(ANError anError) {

                        Log.e("anError", "sending failed, it will generate a EODID222 \n" + anError.getErrorBody());

                        EODIDCatcher = generatedEODID;

                        String queryEOD = ("update " + DBHelper.TRANS_EOD + " set " + DBHelper.TRANS_EOD_RETURN_ID + " = '" + generatedEODID + "',is_send = '2' where control_no = '" + control_no + "' and trip_no = '" + trip_no + "' ");
                        sqldb.execSQL(queryEOD);

                        String updateEODIDDispatch = ("update " + DBHelper.TRANS_DISPATCH + " set " + DBHelper.TRANS_DISPATCH_EOD_ID + " = '" + generatedEODID + "' where control_no = '" + control_no + "' and trip_no = '" + trip_no + "' ");
                        sqldb.execSQL(updateEODIDDispatch);

                        String updateTransSettingsEODID = ("update " + DBHelper.TRANS_SETTINGS + " set " + DBHelper.TRANS_EOD_RETURN_ID + " =  '" + generatedEODID + "' where control_no = '" + control_no + "' and trip_no = '" + trip_no + "' ");
                        sqldb.execSQL(updateTransSettingsEODID);


                        Log.e("EODIDCatcher ERROR", EODIDCatcher);
                        countDownLatch.countDown();
                    }
                });
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

请问哪里出错了?而且它没有执行我的第二个功能?谢谢!

它被阻止了,因为你的 sendAndgetEODID(countDownLatch); 不会 运行 完成。 await 导致当前线程等待,直到锁存器倒计时到零。当您收到响应(异步)时,countDownLatch.await(); 将被触发(因为它是同步的)并导致线程等待。

解决方案:

方法一:

如果您打算在执行 sendAndgetEODID(countDownLatch); 调用后执行 sendAndgetDispID();,则只需将 countDownLatch.countDown(); 替换为 sendAndgetDispID();,如下所示:

new JSONObjectRequestListener() {

    @Override
    public void onResponse(JSONObject response) {
        Log.e("response EOD", String.valueOf(response));

        try {
            ...
            sendAndgetDispID();

        } catch (JSONException e) {
            e.printStackTrace();
            sendAndgetDispID();
        }
    }

    @Override
    public void onError(ANError anError) {

       ...
        sendAndgetDispID();
    }
});

方法二:

在不同线程中处理 AndroidNetworking.post。这可能会导致一些多线程问题,因此您需要小心并有效地使用同步块。