简体   繁体   English

AsyncTask ProgressBar 更新中的多线程概念 wait() 和 notify()

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM