我正在开发Android移动应用程序,该应用程序本身最重要的功能之一是能够与第三方API服务进行通信。
提供这些API的第三方服务需要一个"信标"被包含在我做的每个API请求中。
"信标"是一个长整数"对于每个请求,它必须是唯一的和增量的。
问题是: 我发出了一些这样的请求,我不知道这些请求中的哪一个会先完成,所以我遇到了竞争条件:第二个请求在第一个请求无效第一个请求之前快速结束!
单击按钮时,将执行以下操作:
public void fireRequests(View view)
{
long first_beacon = System.nanoTime();
fireFirstRequest(view, first_beacon);
long second_beacon = System.nanoTime();
fireSecondRequest(view, second_beacon);
}
我正在以适当的方式使用Volley,设置回调等。例如:
fireFirstRequest方法:
public void fireFirstRequest(View view, long beacon)
{
final ThirdPartyLib api_lib = new ThirdPartyLib(getActivity());
api_lib.doOperationA(beacon, new ThirdPartyLib.MyOwnCallback()
{
@Override
public void update(JSONObject jsonObject)
{
try
{
JSONObject result = jsonObject.getJSONObject("response");
/* my code */
Log.d("doOperationA", result)
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
}
fireSecondRequest方法:
public void fireSecondRequest(View view, long beacon)
{
final ThirdPartyLib api_lib = new ThirdPartyLib(getActivity());
api_lib.doOperationB(beacon, new ThirdPartyLib.MyOwnCallback()
{
@Override
public void update(JSONObject jsonObject)
{
try
{
JSONObject result = jsonObject.getJSONObject("response");
/* my code */
Log.d("doOperationB", result)
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
}
这是执行日志:
03-12 14:26:56.252 18769-18769/it.example.app D/Volley: queued doOperationA
03-12 14:26:58.124 18769-18769/it.example.app D/Volley: queued doOperationB
03-12 14:26:59.433 18769-18769/it.example.app D/App: doOperationB: {
"error": false,
"payload": {
"foo": "bar"
}
}
03-12 14:27:04.181 18769-18769/it.example.app D/App: doOperationA: {
"error": true,
"errorMessage": "invalid beacon"
"payload": {}
}
问题是:在发出API请求之前跟踪信标的最佳方法是什么,或者维持"执行顺序"即使我们谈论ASync请求也要分离?
我的粗略解决方案是在我完全确定第一个请求完成时,在fireFirstRequest()的回调中调用fireSecondRequest()。 我知道,这是杀死异步请求的绝佳世界的最好方法。
修改后的行动:
public void fireRequests(View view)
{
long first_beacon = System.nanoTime();
fireFirstRequest(view, first_beacon);
}
使用最终查看参数
的fireFirstRequest修改方法public void fireFirstRequest(final View view, long beacon)
{
final ThirdPartyLib api_lib = new ThirdPartyLib(getActivity());
api_lib.doOperationA(beacon, new ThirdPartyLib.MyOwnCallback()
{
@Override
public void update(JSONObject jsonObject)
{
try
{
JSONObject result = jsonObject.getJSONObject("response");
/* my code */
Log.d("doOperationA", result)
/* fire second request */
// EDIT
fireSecondRequest(view, System.nanoTime());
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
}
答案 0 :(得分:0)
您没有添加启动Volley RequestQueue
的代码部分,但我假设您正在使用以下方式创建默认方式:
RequestQueue requestQueue = Volley.newRequestQueue(context, stack);
执行此操作时,您将获得一个请求队列,默认情况下允许4个并发请求。您可以通过查看此方法用于创建请求队列的构造函数来查看此内容:
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
...
public RequestQueue(Cache cache, Network network) {
this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
}
如果不是使用默认方法创建RequestQueue
,而是创建自己的RequestQueue
,线程池大小为1,则可以解决此问题。这样,就不会有2个并发请求和请求将按照发送的顺序发送。
当然,这样做的缺点是,这会大大减慢您的应用。如果所有请求必须等到上一个请求完成,这会在您的应用中造成严重的瓶颈。
也许考虑使用多个请求队列,并且只对依赖此特殊约束的请求使用此特殊请求队列。
希望这有帮助。