So in my further attempts to implement a while loop in android I have come up with the code below :
private boolean connected = false;
private Thread loop = new Thread() {
public void run() {
Looper.prepare();
while (connected) {
do_Something();
}
Looper.loop();
}
};
onCreate() {
//.....
ok = (Button) findViewById(R.id.button1);
ok.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (connected) {
try {
loop.start();
}
catch (Exception e) {
Toast.makeText(getBaseContext(), "Exception caught", Toast.LENGTH_LONG).show();
}
}
return true;
}
});
stop = (Button)findViewById(R.id.button2);
stop.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//disconnects current connection
connected = false;
}
return true;
}
});
}
That is, I am trying to on the touch of the first button have my UI thread switch to the thread that will do_something over and over again until the touch of the second button, in which case the boolean var k will switch off and completely stop the newly created thread from the button press of the first button. I have google'd "threads/handlers/android while loops" but to no avail. Any help towards what I am trying to do would be much appreciated
Simply put, how do I kill the thread that was created via pressing the second button?
Did you tried AsyncTask ? What you can do...start a new AsyncTask on firstButton click and cancel it on secondButton click.
//define global variable
private DoSomething doSomething;
//register firstButton onClickListener
firstButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
//start your asynctask
if(doSomething == null || doSomething.isCancelled()){
doSomething = new DoSomething();
doSomething = doSomething.execute();
}
}
});
//register secondButton onClickListener
secondButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
doSomething.cancel();
}
});
//Inner AsyncTask class
class DoSomething extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
//doSomething();
while(true){
System.out.println(1);
if(isCancelled()){
break;
}
}
return null;
}
}
Note: This is pseudocode...might contain error...just want to give you overview. hope this help.
Related
Why does the View.OntouchListener stops working after thread.start?
Here's my code:
public class MultiviewActivity extends Activity implements Runnable {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
c = getBaseContext();
handler = new myHandler();
final GestureDetector detector = new GestureDetector(c, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
#Override
public boolean onDown(MotionEvent e) {
Log.i("multiView", "Touch id=" + viewid);
return true;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
}
});
View.OnTouchListener touchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
viewid = v.getId();
return detector.onTouchEvent(event);
}
};
LinearLayout lay = findViewById(R.id.l1);
lay.setOnTouchListener(touchListener);
//timer
Runnable timerrunnable = new Runnable() {
#Override
public void run() {
if (!bisruning) {
thread = new Thread(MultiviewActivity.this);
thread.start();
}
timerhandler.postDelayed(this, 1000);
}
};
timerhandler.postDelayed(timerrunnable, 5000);
}
#Override
public void run() {
bisruning = true;
msg = handler.obtainMessage();
Log.i("multiView", "Running thread");
//thread task goes here...
msg.arg1 = 0;
msg.arg2 = 1;
handler.sendMessage(msg);
}
class myHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.arg1) {
case 0:
if (msg.arg2 == 1)
fillLayout();
bisruning = false;
break;
}
}
}
}
As soon as my timer ticks in (after 5s), the view stops responding to screen taps...
I know that the View is responding to taps before the thread starts because I've logged the OnDown event.
What am I doing wrong?
Thank you for your help.
Regards
I am developing a android app, this is a requirement. I need different functionality on onclick and also different functionality on stop and start method of ontouch. can any one help me? How can i implement this feature in android?
I understand your problem and i hope below code will be help you.
public class MyFragment extends BaseFragment implements View.OnTouchListener {
#Override
public boolean onTouch(final View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
prev_timestamp = System.currentTimeMillis();
case MotionEvent.ACTION_UP:
current_timestamp = System.currentTimeMillis();
upcount++;
if (current_timestamp - prev_timestamp < 250) {
if (upcount == 2) {
upcount = 0;
Log.d(TAG, "click event");
//here code for onClick event
} else {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
if (upcount != 0) {
TOUCH_END=false;
Log.d(TAG, "touch start");
//here code for onTouchStart event
}
super.onPostExecute(aVoid);
}
}.execute();
}
} else {
upcount = 0;
Log.d(TAG, "touch end");
//here code for onTouchEnd event
}
case MotionEvent.ACTION_CANCEL:
//here code for cancel eent if you want
}
return true;
}
}
Source :see example here
I have set ontouch listener to implement a counter for my imagebutton. But I can only detect button being touched and release. I am not sure how to implement incrementing as long as the button is pressed and how to stop it after it is released. Following is the code I have:
up.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
pressdown();
}
else if (event.getAction()==MotionEvent.ACTION_UP) {
pressrelease();
}
return true;
}
Ok. Here's a solution to my own question. It might help someone else.
use a Handler object because you have to implement a separate thread for incrementing/decrementing
public class MainActivity extends Activity{
private boolean autoIncrement = false;
private boolean autoDecrement = false;
private final long REPEAT_DELAY = 50;
private Handler repeatUpdateHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.input);
class RepetitiveUpdater implements Runnable{
#Override
public void run() {
if (autoIncrement) {
increment();
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(), REPEAT_DELAY);
}
else if(autoDecrement){
decrement();
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(), REPEAT_DELAY);
}
}
}
up.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
increment();
}
});
up.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
autoIncrement = true;
repeatUpdateHandler.post(new RepetitiveUpdater());
return false;
}
});
up.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP && autoIncrement ){
autoIncrement = false;
}
return false;
}
});
public void increment(){
if (i<100) {
i++;
TextView no = (TextView)findViewById(R.id.no);
no.setText(String.valueOf(i));
}
}
}
Do the same for decrement.
Courtesy: Github, author: Jeffrey F. Cole
I am creating an Android app to control the mouse of my PC. The application has 4 buttons (left, right, up, down). On clicking on them the application sends an integer to pc, the Java application running on PC will receive it and moves the cursor.
Now all I want to do is when user press a button for long time, the application has to send the number continuously to pc until user releases the button. Someone please help me to do this.
Use OnTouchListener to listen for MotionEvent.ACTION_DOWN and when it happens start sending appropriate signal to computer for example each 0.5 seconds. Stop doing this after MotionEvent.ACTION_UP.
EDIT:
public class MainActivity extends Activity implements OnTouchListener {
private TextView TV;
private Thread move_curser;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TV = (TextView) findViewById(R.id.TV1);
TV.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent event) {
boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN;
boolean isReleased = event.getAction() == MotionEvent.ACTION_UP;
if(isPressed) {
move_curser = new Thread(new move_curser());
move_curser.start();
your_methode();
return true;
} else if(isReleased){
move_curser.interrupt();
return true;
}
return false;
}
public class move_curser implements Runnable {
public void run() {
int time = 500;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
interrupt();
}
while(true){
your_methode();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
interrupt();
}
}
}
}
}
i doing simple stop watch with [start/pause] and [reset] button. problem occur when i pressed start button after pause. the run method is not calling. please help me.
my code is
public class StopWatch3 extends Activity implements Runnable{
// text view influenced by the Thread
private TextView threadModifiedText;
int time=0;
Button b1,b2,b3;
boolean shouldRun = false;
/** Called when the activity is first created. */
Thread currentThread = new Thread(this);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stopwatch);
b1=(Button)findViewById(R.id.button1);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.button3);
threadModifiedText = (TextView) findViewById(R.id.textView1);
Log.e("before",""+currentThread.getState());
b1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
Log.e("stopw",(String) b1.getText());
if(b1.getText().toString().equals("start")){
if(currentThread.getState()==Thread.State.NEW){
currentThread.start();
Log.e("after",""+currentThread.getState());
shouldRun = true;
b1.setText("pause");
}
else{
shouldRun = true;
b1.setText("pause");
}
}
else if(b1.getText().toString().equals("pause")){
shouldRun = false;
b1.setText("start");
}
}
});
b2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
time=0;
}
});
}
#Override
public void run(){
try {
while(shouldRun){
Thread.sleep(1000);
threadHandler.sendEmptyMessage(0);
}
} catch (InterruptedException e) {
}
}
private Handler threadHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
time++;
threadModifiedText.setText(""+time);
}
};
}
You cannot start thread after it finishes it's job, and his state is no longer NEW anyway, you'll have to create a new thread in this case.
When you press "start" the second time, you reach this part:
else{
shouldRun = true;
b1.setText("pause");
}
And nothing in this code will make the thread run again of course...
I think your thread just runs to an end when you set shouldRun to false.
Enclose your while loop into another while loop that is true as long as your program runs.