2017-03-07 3 views
0

this solutionを参照して、AsyncTaskを複数回実行します。しかし、私は複数のAsyncTaskを実行中のjava.lang.IllegalMonitorStateException

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) 

tryAgain.signal();は私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から空の応答を得たとき、私は​​と呼ばれ、アプリケーションはクラッシュしました。 この例外を処理する解決策を教えてください。

+0

[Execute AsyncTaskを何度も実行する](http://stackoverflow.com/questions/6373826/execute-asynctask-several-times) – FabioBranch

+0

@FabioBranch私はそのスレッドを参照しましたが、実装中に問題に直面しています。 –

答えて

0

Condition before call信号に関連付けられたロックを取得する必要があります。

public void runAgain() { 
    // Call this to request data from the server again 
    lock.lock(); 
    try { 
     tryAgain.signal(); 
    } finally { 
     lock.unlock(); 
    } 
} 

あなたが参照した解決方法には独自のバグがあります。

以下はAndroid API Referenceからコピーされています。

実装に関する考慮事項

実装(典型的にはないが)このメソッドが呼び出されたときに、現在のスレッドがこの条件に関連付けられているロックを保持することを必要とするかもしれません。実装では、この前提条件と、ロックが保持されていない場合に実行されるアクションを記録する必要があります。通常、IllegalMonitorStateExceptionなどの例外がスローされます。

ジョブを複数回実行する必要がある場合は、スレッド、ハンドラ、またはサービスをAsyncTaskよりも優れた方法にすることができます。

+0

しかし私のシナリオではロックを取得する方法は? 'lock.unlock();'を 'doInBackground()'から削除すると、そのロックが破棄されます。 –

+0

ありがとうございます。その作品! –

関連する問題