简体   繁体   English

For循环内的Android postDelayed处理程序?

[英]Android postDelayed Handler Inside a For Loop?

Is there any way of running a handler inside a loop?有没有办法在循环内运行处理程序? I have this code but is not working as it does not wait for the loop but executes the code right way:我有这段代码,但没有工作,因为它不等待循环而是以正确的方式执行代码:

final Handler handler = new Handler();


        final Runnable runnable = new Runnable() {
            public void run() {

                // need to do tasks on the UI thread
                Log.d(TAG, "runn test");

                //
                for (int i = 1; i < 6; i++) {

                    handler.postDelayed(this, 5000);

                }


            }
        };

        // trigger first time
        handler.postDelayed(runnable, 0);

Of course when I move the post delayed outside the loop works but it does not iterate nor execute the times I need:当然,当我在循环之外移动延迟的帖子时,但它不会迭代也不会执行我需要的时间:

final Handler handler = new Handler();


        final Runnable runnable = new Runnable() {
            public void run() {

                // need to do tasks on the UI thread
                Log.d(TAG, "runn test");

                //
                for (int i = 1; i < 6; i++) {
                }

                // works great! but it does not do what we need
                handler.postDelayed(this, 5000);


            }
        };

        // trigger first time
        handler.postDelayed(runnable, 0);

SOLUTION FOUND:找到的解决方案:

I need to use asyntask along with Thread.sleep(5000) in the doInBackground method:我需要在 doInBackground 方法中使用 asyntask 和 Thread.sleep(5000) :

class ExecuteAsyncTask extends AsyncTask<Object, Void, String> {


            //
            protected String doInBackground(Object... task_idx) {

                //
                String param = (String) task_idx[0];

                //
                Log.d(TAG, "xxx - iter value started task idx: " + param);

                // stop
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //
                Log.d(TAG, "xxx - iter value done " + param);
                return " done for task idx: " + param;
            }


            //
            protected void onPostExecute(String result) {
                Log.d(TAG, "xxx - task executed update ui controls: " + result);
            }

        }




        for(int i = 0; i < 6; i ++){

            //
            new ExecuteAsyncTask().execute( String.valueOf(i) );

        }

Instead of using a for loop, you can let the Runnable instance call itself for a specific number of times.您可以让Runnable实例调用自身特定次数,而不是使用for循环。 These calls will be posted to UI thread queue so, keep that in mind.这些调用将发布到 UI 线程队列,因此请记住这一点。 Also, since the delay is quite large, make sure the event is still needed when you trigger it next time.另外,由于延迟非常大,请确保下次触发时仍然需要该事件。

The following code should do it:下面的代码应该这样做:

final Handler handler = new Handler(); 
int count = 0;

final Runnable runnable = new Runnable() {
    public void run() { 
        // need to do tasks on the UI thread 
        Log.d(TAG, "Run test count: " + count);
        if (count++ < 5) {
            handler.postDelayed(this, 5000);
        }
    } 
}; 

// trigger first time 
handler.post(runnable);

My solution to this problem if anyone has simmilar issues:如果有人遇到类似问题,我对此问题的解决方案是:

int count = 0;
    public static void method(param1, param2, param3) {
                        Runnable r = () -> { //put method inside runnable
                        View view = listView.getChildAt(position); //action to be complete
                        if (view != null) { //if action is successfully complete
                            view.setSelected(true); //do something with this 
                        } else { //do a looper
                            if (count < 10) { //limited looper to certain number
                                count++;
                                method(param1, param2, param3); //run the method again
                        }
                };

                Handler h = new Handler(); //create a new Handler and post above thread with it
                h.postDelayed(r, 300);
             }

Basically, I have created an if-else statement where else statement runs the same method with postDelayed() again for a limited number of trials.基本上,我创建了一个 if-else 语句,其中 else 语句再次使用postDelayed()运行相同的方法,以进行有限次数的试验。

This can be another solution这可以是另一种解决方案

final Handler handler = new Handler();
Runnable runnable = new Runnable() {
    int i;
    public void run() {
        for (i = 1; i < 6; i++) {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    // need to do tasks on the UI thread
                    Log.d(TAG, "runn test");
                }
            }, 0);
            //Add some downtime
            SystemClock.sleep(5000);
        }
    }
};
new Thread(runnable).start();

Here is a simple logic I made, without moving the for loop inside runnable .这是我制作的一个简单逻辑,没有在runnable移动for loop

 for(int i = 1; i<=5; i++){
    ...
    new Handler().postDelayed(() -> myFunctionToExecute() , i * 1000);
 }

So whenever the loop iterates, it just extends the handler delay.所以每当循环迭代时,它只会延长处理程序延迟。 And this way, you may achieve.这样,您就可以实现。 I was searching for something similar, couldn't find anything, because in my case I already did the implementation of for loop, moving it inside the run() creates a mess我正在寻找类似的东西,找不到任何东西,因为在我的情况下,我已经实现了 for 循环,将它移动到 run() 中会造成混乱

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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