Oscar Méndez
Oscar Méndez

Reputation: 1007

Button to stop a for loop on Android

I want to stop a for loop with a button, but I can't make it work.

  1. I have a boolean to indicate that the button had not been pressed before. when the button is pressed, the boolean changes to indicate that was pressed, starts the method AccionPorSegundo, and and changes the button text to "stop".

  2. In AccionPorSegundo there is a loop that lasts 40 seconds.

  3. if you press the button, now with the text "stop", the loop stops

This is my code, but it doesn't work:

public class EL_Entrenamiento extends ActionBarActivity implements View.OnClickListener {
    Handler mHandler = new Handler();
    TextView tv1,tv2;
    int a = 1;
    int max = 9;
    int min = 0;
    int i = 1;
    Button comenzar;
    Boolean exit = false;
    Boolean presionado = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.el_entrenamiento_layout);

        comenzar = (Button) findViewById(R.id.bt_el_entrenamiento_comenzar);
        tv1 = (TextView) findViewById(R.id.tv_El_entrenamiento1);
        tv2 = (TextView) findViewById(R.id.tv_El_entrenamiento2);

        comenzar.setOnClickListener(this);

        //ACTION BAR PERSON
        BitmapDrawable bg = (BitmapDrawable)getResources().getDrawable(R.drawable.ab_background_textured_rojo);
        bg.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        getSupportActionBar().setBackgroundDrawable(bg);

        BitmapDrawable bgSplit = (BitmapDrawable)getResources().getDrawable(R.drawable.bg_striped_split_img);
        bgSplit.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        getSupportActionBar().setSplitBackgroundDrawable(bgSplit);
        getSupportActionBar().setLogo(R.drawable.ic_action_entrenamiento);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        //FONFO BOTON PERSON
        comenzar.setBackgroundDrawable(bg);
    }

    final Handler handler = new Handler();
    final Timer timer = new Timer();
    final Runnable doA = new Runnable() {
        @Override
        public void run() {
            Random rand = new Random();

            int randomNum1 = rand.nextInt((max - min) + 1) + min;
            int randomNum2 = rand.nextInt((max - min) + 1) + min;
            tv1.setVisibility(View.VISIBLE);
            tv2.setVisibility(View.VISIBLE);
            tv1.setText("" + randomNum1);
            tv2.setText("" + randomNum2);

            tv1.postDelayed(new Runnable() {
                public void run() {
                tv1.setVisibility(View.INVISIBLE);
                tv2.setVisibility(View.INVISIBLE);
                    if (a==41){
                        comenzar.setText("Comenzar");
                    }
                }
            }, 500);
            a++;
        }
    };

    public void AccionPorSegundo(){

            for ( i = 1; i <= 40; i++) {
                    if (this.exit) break;
                    TimerTask task = new TimerTask() {
                        @Override
                        public void run() {
                            handler.post(doA);
                        }
                    };
                    timer.schedule(task, i * 1000);
            }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.bt_el_entrenamiento_comenzar:
                if (!presionado){
               presionado=true;
                AccionPorSegundo();
                comenzar.setText("Stop");
                }else{
                    exit=true;
                    comenzar.setText("Comenzar");
                }

        }
    }
}

Can anyone help me with this?

Upvotes: 0

Views: 955

Answers (2)

Valentin Filyov
Valentin Filyov

Reputation: 632

martijnn2008's answer is helpful but I had the same issue and solved it by using "either" the exit "or" i < 40 . I changed && exit to || exit so that it can be stopped from both of them independently :)

Upvotes: 0

martijnn2008
martijnn2008

Reputation: 3640

You are starting 40 Threads with that for-loop. Why dont use 1 thread and do all the work in there? Then you stop de loop with setting a boolean exit = false

for(int i=0; i<40 && exit; i++) {
  // do the things you want
}

I guess with the way you have it now, the 40 seconds he is bussy starting the thread you cant press the button. In order to change that make sure that heavy CPU-usage is not executed on the UI-threath.

Upvotes: 1

Related Questions