我引用this solution多次运行AsyncTask。但是当我拨打tryAgain.signal();
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.webapi_testing, PID: 3951
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1917)
at com.medimanage.webapi_testing.AsyncHttpRequest_Recursive.runAgain(AsyncHttpRequest_Recursive.java:156)
at com.medimanage.webapi_testing.AsyncHttpRequest_Recursive.onProgressUpdate(AsyncHttpRequest_Recursive.java:145)
at com.medimanage.webapi_testing.AsyncHttpRequest_Recursive.onProgressUpdate(AsyncHttpRequest_Recursive.java:17)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:648)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5052)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
以下是我的asyncTask类;
public class AsyncHttpRequest extends AsyncTask<Void, String, String> {
private String UrlString = "";
private boolean _showProgressDialog = false;
private ProgressDialog Dialog;
private Context mContext;
private IHttpRequestCompletedListener listener;
private boolean isActivity = true;
private String _messageText = "Please wait...";
private String type = "get";
private HttpUtility utility;
private final ReentrantLock lock = new ReentrantLock();
private final Condition tryAgain = lock.newCondition();
private volatile boolean finished = false;
boolean lockAcquired = false;
public AsyncHttpRequest(String urlString, Context context, IHttpRequestCompletedListener listener, boolean _showProgressDialog) {
UrlString = urlString;
this._showProgressDialog = _showProgressDialog;
this.mContext = context;
this.listener = listener;
Dialog = new ProgressDialog(this.mContext);
this.utility = new HttpUtility(this.UrlString, mContext, listener);
}
public void addGetHeader(String headerData) {
this.utility.addGetHeader(headerData);
}
public void setWaitMessage(String msgText) {
if (!msgText.equals(""))
msgText = "\n" + msgText;
this._messageText = _messageText + msgText;
}
@Override
protected void onPreExecute() {
if (_showProgressDialog) {
Dialog.setMessage(this._messageText);
Dialog.setCancelable(false);
Dialog.setCanceledOnTouchOutside(false);
Dialog.show();
}
}
@Override
protected String doInBackground(Void... params) {
try {
String result = "";
lock.lockInterruptibly();
do {
if (!Utilities.isNetworkAvailable(mContext))
result = "No network available";
else if (this.type.equals("get"))
result = utility.doGetRequest();
else
result = utility.doPostRequest();
publishProgress(result);
tryAgain.await();
} while (!finished);
lock.unlock();
return result;
} catch (MediCorporateException tex) {
if (listener != null) {
if (isActivity) {
((Activity) mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
listener.OnHttpRequestError();
}
});
}
} else {
((GcmIntentService) mContext).runOnUIThread(new Runnable() {
@Override
public void run() {
listener.OnHttpRequestError();
}
});
}
}
}
Utilities.callCrashReport(mContext, tex);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}finally {
lock.unlock();
}
return "";
}
@Override
protected void onProgressUpdate(String... values) {
if (this.listener != null) {
if(values.length > 0) {
if (!Utilities.isNullOrEmpty(values[0])) {
listener.OnHttpRequestCompleted(values[0]);
terminateTask();
} else {
runAgain();
}
}else {
runAgain();
}
}
Log.i("Exit ", "onProgressUpdate");
}
public void runAgain() {
// Call this to request data from the server again
tryAgain.signal();
}
public void terminateTask() {
// The task will only finish when we call this method
if (_showProgressDialog)
this.Dialog.dismiss();
finished = true;
if(lock.isHeldByCurrentThread())
{
lock.unlock();
}
}
@Override
protected void onPostExecute(String Result) {
Log.i("Exit ", "onPostExecute");
}
}
当我从WebService获得空响应时,我调用了runAgain()
并且应用程序崩溃了。
请提供任何解决方案来处理此异常。
答案 0 :(得分:1)
你应该获得一个与呼叫前信号相关的锁。
public void runAgain() {
// Call this to request data from the server again
lock.lock();
try {
tryAgain.signal();
} finally {
lock.unlock();
}
}
您引用的解决方案有自己的错误。
以下内容从Android API Reference复制。
实施注意事项
当调用此方法时,实现可能(并且通常确实)要求当前线程保持与此Condition关联的锁。实现必须记录此前提条件以及未保持锁定时所采取的任何操作。通常,会抛出异常,例如IllegalMonitorStateException。
如果作业应该多次执行,那么Thread,Handler或Service可能是比AsyncTask更好的选择。