Android postDelayed Handler Inside a For Loop?

2019-06-28 07:57发布

问题:

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:

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) );

        }

回答1:

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, "runn test");


                if (count++ < 5)
                    handler.postDelayed(this, 5000);

            } 
        }; 

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


回答2:

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.



回答3:

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();