[英]Multi threading concept wait() and notify() inside AsyncTask ProgressBar update
Here inside background method need to call multiple API request based on the size of the list.这里里面的后台方法需要根据列表的大小调用多个 API 请求。 But i'm using while().
但我正在使用 while()。 It is not wait un till request API and get response.
不是等到请求 API 并得到响应。 So am using thread inside.
所以我在里面使用线程。 How to synchronized.
如何同步。 Once the API call get success after only need to call next request.
一旦 API 调用成功后,只需要调用下一个请求。
private class AsyncPost extends AsyncTask<String, Void, Void> {
String strResult = "";
@Override
protected Void doInBackground(String... params) {
try {
GlobalVariables.rqCount=0;
mHandler=null;
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(android.os.Message message) {
onProgressUpdate(message.getData().getString("MessageString"));
}
};
strResult = "ENSURE NOT EMPTY";
strResult=getRequestResult(Listactivity.this,50, mHandler);
}
catch (Exception e)
{
dialog.dismiss();
}
return null;
}
@Override
protected void onPostExecute(Void resultGetlogin) {
try {
dialog.dismiss();
if(strResult.equals("Success")){
CustomDiallog.showAlertDialog(Listactivity.this, "Successfully!!");
}else{
CustomDiallog.showAlertDialog(Listactivity.this, "FAIL!!");
}
} catch (Exception e) {
dialog.dismiss();
}
}
protected void onProgressUpdate(String... values) {
dialog.setMessage(""+values[0]);
}
protected void onPreExecute() {
dialog = ProgressDialog.show(Sync_Bulk.this, "", "");
}
}
This thread am using but getting crash help me该线程正在使用但崩溃帮助我
private class getRequestResult(Context context, int allSyncLimit,Handler handler2){
new Thread(new Runnable() {
@Override
public void run() {
try {
inalContext.wait();
if (res_result.equals("Success")) {
result[0] = "Success";
} else {
result[0] = "fail";
}
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (finalContext) {
postRequest((Activity) finalContext, list); // This is Api method and notify() is called
}
}
}).start();
}
}
You need something similar to:你需要类似的东西:
/** Class for Synchronize two Threads */
private static class SyncObj<T> {
@Nullable
private T mValue = null;
public SyncObj(@Nullable final T initValue) { this.mValue = initValue; }
public void set(@Nullable final T value) { this.mValue = value; }
@Nullable
public T get() { return this.mValue; }
}
/** A Thread is used instead of {@link AsyncPost} */
private class AsyncPost extends Thread {
private Handler mAsyncPostHandler;
private final Handler mMainThreadHandler;
private boolean mOnPreExecuted = false;
public AsyncPost() {
mMainThreadHandler = new Handler(Looper.getMainLooper()) {
@UiThread @MainThread
@Override
public void handleMessage(@NonNull final Message message) {
switch (message.what) {
case 111: {
@Nullable
final String cRequestText = (String)message.obj;
if (cRequestText == null) break;
dialog.setMessage(cRequestText);
break;
}
default: { } //all Runnables sent to "mMainThreadHandler" are executed "here"
}
}
};
}
@WorkerThread
@Override
public void run() {
Looper.prepare();
mAsyncPostHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(@NonNull final Message message) {
switch (message.what) {
case -1: {
final Looper cMyLooper = Looper.myLooper();
if (cMyLooper != null) cMyLooper.quit();
break;
}
case 555: {
if (!mOnPreExecuted) {
//esecuted on Main/UIThread at first API Request...
OnMainThreadRun(new Runnable() { //SAME AS "onPreExecute()"
@Override
public void run() { dialog = ProgressDialog.show(Sync_Bulk.this, "", ""); }
});
mOnPreExecuted = true;
}
final List<?> cList = (List<?>)message.obj;
if (cList == null) break;
final SyncObj<String> cSyncObj = new SyncObj<>(null);
//loop through the List
@Nullable
String cRequesteResult;
for (final Object cItem : cList) {
//call API Request for each item in the List...
postRequest(cSyncObj, cItem);
try {
//...wait until "notify()" is called
synchronized (cSyncObj) {
//loop until "SyncObj.set()" was called with a valid Value
while ((cRequesteResult = cSyncObj.get()) == null) cSyncObj.wait();
//check SyncObj result
if (cRequesteResult.equals("OK")) {
Log.i("MainActivity", "Request successfully");
} else {
Log.w("MainActivity", "Request failed: " + cRequesteResult);
}
//update the Dialog on Main/UIThread
OnProgressUpdate(cRequesteResult);
}
} catch (Exception e) {
Log.e("MainActivity", "Stopping all Request due to Exception: " + e.getMessage());
}
}
//terminate this Thread
postToAsyncThread_Quit();
break;
}
}
}
};
Looper.loop();
this.OnMainThreadRun(new Runnable() { //SAME AS "OnPostExecute()"
@Override
public void run() {
..executed on Main/UIThread at the end of all..
}
});
}
/** Execute a {@link Runnable} on MainThread/UiThread */
@WorkerThread
private void OnMainThreadRun(@Nullable final Runnable runnable) {
if (runnable == null) return;
mMainThreadHandler.post(runnable);
}
@AnyThread
private void OnProgressUpdate(@Nullable final String text) { mMainThreadHandler.sendMessage(Message.obtain(mMainThreadHandler, 111, text)); }
/** Execute a {@link Runnable} on {@link AsyncPost} Thread */
@AnyThread
private void postToAsyncThread_DoRequests(@Nullable final List<?> list) { mAsyncPostHandler.sendMessage(Message.obtain(mAsyncPostHandler, 555, list)); }
/** Terminate {@link AsyncPost} Thread */
@AnyThread
private void postToAsyncThread_Quit() { mAsyncPostHandler.sendEmptyMessage(-1); }
}
private void postRequest(final SyncObj<String> syncObj, @NonNull final Object listItem) {
//execute API Request which will trigger one of Listener methods
doAsyncRequest(listItem, new ResponseListener() {
@Override
void onSuccess() {
synchronized (syncObj) {
syncObj.set("OK");
syncObj.notify();
}
}
@Override
void onFailed() {
synchronized (syncObj) {
syncObj.set("ERROR");
syncObj.notify();
}
}
});
}
private void doAllRequests(@Nullable final List<?> list) {
final AsyncPost cAsyncPost = new AsyncPost();
cAsyncPost.start();
cAsyncPost.postToAsyncThread_DoRequests(list);
}
Just call "doAllRequests(...)" providing the appropriate List.只需调用“doAllRequests(...)”提供适当的列表。 A single "OnPreExecute()"-like will be executed at first API call and a single "OnPostExecute()"-like will be executed at the end of last APi call.
在第一次 API 调用时将执行一个类似“OnPreExecute()”,在最后一次 APi 调用结束时将执行一个类似“OnPostExecute()”。 At each API Call (success or fail) "case 111:" will be called from the Main/UIThread.
在每个 API 调用(成功或失败)“案例 111:”将从 Main/UIThread 调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.