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
。这可能会导致一些多线程问题,因此您需要小心并有效地使用同步块。
我正在处理 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
。这可能会导致一些多线程问题,因此您需要小心并有效地使用同步块。