-2

I want to have an android app, in which the background is flashing as long as I'm pressing a button. This works, but when I release the button the background doesn't stop flashing. I think the reason is that I'm using a Thread. I don't know exactly how to stop it(and I'm working the first time with Threads). I thought I could write in the Action_Up Event of the Button "threadname.stop()" but Android studio cannot resolve the name. So: how can I stop the Thread so that the the Action_Up case gets performed ? Thank You very much !!!

My MainActivity code:

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {

    Button flash;
    RelativeLayout layout;
    boolean backgroundisblack;

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

        backgroundisblack = true;
        layout = (RelativeLayout)findViewById(R.id.layout);
        flash = (Button)findViewById(R.id.flash );

        //Button
        flash.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {


                //button is pressed
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:{

                        //thread
                        Thread t = new Thread(){
                            @Override
                            public void run(){
                                while(!interrupted()){
                                    try {
                                        Thread.sleep(1000);

                                        runOnUiThread(new Runnable(){
                                            @Override
                                            public void run(){
                                               //action
                                                if(backgroundisblack){
                                                    layout.setBackgroundColor(Color.WHITE);
                                                    backgroundisblack = false;
                                                }else if (!backgroundisblack){
                                                    layout.setBackgroundColor(Color.BLACK);
                                                    backgroundisblack = true;
                                                }



                                            }
                                        });
                                    }catch (InterruptedException e){
                                        e.printStackTrace();
                                    }
                                }
                            }
                        };
                        t.start();


                        break;
                    }

                    //button is released
                    case MotionEvent.ACTION_UP:{
                        layout.setBackgroundColor(Color.BLACK);

                        break;
                    }
                }
                return false;
            }
        });


    }
}
user7940193
  • 117
  • 2
  • 10
  • 1
    Possible duplicate of [How do you kill a thread in Java?](https://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java) – user1643723 Jun 18 '17 at 12:24

4 Answers4

0

Add a field needToRun default is true. Continue the while loop while: !interrupted()&&needToRun. set needToRun to false when detect TOUCH_UP. This is a recommended way to stop a thread in java.

kevin
  • 54
  • 5
0

Set boolean field

private boolean runningThread;

then change run method to:

public void run(){
    runningThread = true;
    while( runningThread ){
    // ...

and on release:

 case MotionEvent.ACTION_UP:{
    runningThread = false; 
    // ...
thorin86
  • 604
  • 11
  • 26
0
  • Make your thread t accessible from case MotionEvent.ACTION_UP to do this define thread t in global scope

  • add t.interrupt() to case MotionEvent.ACTION_UP

it will look like

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {

Button flash;
RelativeLayout layout;
boolean backgroundisblack;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    backgroundisblack = true;
    layout = (RelativeLayout)findViewById(R.id.layout);
    flash = (Button)findViewById(R.id.flash );
    //Button
    flash.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Thread t;
            //button is pressed
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:{//thread
                    t = new Thread(){
                        @Override
                        public void run(){
                            while(!interrupted()){
                                try {
                                    Thread.sleep(1000);
                                    runOnUiThread(new Runnable(){
                                        @Override
                                        public void run(){
                                           //action
                                            if(backgroundisblack){
                                                layout.setBackgroundColor(Color.WHITE);
                                                backgroundisblack = false;
                                            }else if (!backgroundisblack){
                                                layout.setBackgroundColor(Color.BLACK);
                                                backgroundisblack = true;
                                            }



                                        }
                                    });
                                }catch (InterruptedException e){
                                    e.printStackTrace();
                                }
                            }
                        }
                    };
                    t.start();


                    break;
                }

                //button is released
                case MotionEvent.ACTION_UP:{
                    layout.setBackgroundColor(Color.BLACK);
                    t.interrupt()
                    break;
                }
            }
            return false;
        }
    });

}
}
hasbi
  • 520
  • 3
  • 10
0

you can put one more condition using on button for when it is pressed and when it is released

// this goes somewhere in your class:
  long lastDown;
  long lastDuration;

  ...

  // this goes wherever you setup your button listener:
  button.setOnTouchListener(new OnTouchListener() {
     @Override
     public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
           lastDown = System.currentTimeMillis();
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
           lastDuration = System.currentTimeMillis() - lastDown;
        }
     }
  });

and thereby can use thread.interrupt() to stop thread.