How to stop the thread in Android? - android

I have a thread in my callback function as follows:
#Override
public void onConnectError(final BluetoothDevice device, String message) {
Log.d("TAG","Trying again in 3 sec.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something
}
}, 2000);
}
});
}
I will to close the the above thread when I press the back button or onDestroy. How can I do it. Thank you
#Override
public void onBackPressed() {
// Close or distroy the thread
}
#Override
public void onDestroy() {
// Close or distroy the thread
}

Please do this like
private Handler handler;
private Runnable runnable;
#Override
public void onConnectError(final BluetoothDevice device, String message) {
Log.d("TAG","Trying again in 3 sec.");
runOnUiThread(new Runnable() {
#Override
public void run() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
//Do something
}
};
handler.postDelayed(runnable, 2000);
}
});
}
and
#Override
public void onBackPressed() {
if (handler != null && runnable != null) {
handler.removeCallbacks(runnable);
}
}
and same in onDestroy();

I'm mostly use thread in this way.See its independent in activity
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.abc);
holdConnectionHandler.sendEmptyMessage(0);
}
Handler holdConnectionHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
// do some work
holdConnectionHandler.sendEmptyMessageDelayed(0, 10 * 1000);
}
};
#Override
public void onDestroy() {
super.onDestroy();
holdConnectionHandler.removeCallbacksAndMessages(null);
// or
holdConnectionHandler.removeMessages(0);
}
}
Thanks hope this will help you

Related

Activity.runOnUiThread(Runnable action) only updates view once

In my fragment, I have an AlertDialog and a Bluetooth connection manager. I want to update the AlertDialog with the new states of the Bluetooth connection process, so I used the runOnUiThread(...) method:
getActivity().runOnUiThread(new Runnable() {
#Override
void run() {
interactor = new BluetoothInteractor(getActivity(), new OnBluetoothStatusChangedListener() {
#Override
public void OnConnectionStopped() {
alertDialog.setMessage("Disconnected.");
}
#Override
public void OnConnectionStopping() {
alertDialog.setMessage("Stopping connection...");
}
#Override
public void OnConnectionStarting() {
alertDialog.setMessage("Connecting to device...");
}
#Override
public void OnConnectionStarted() {
alertDialog.setMessage("Streaming data...");
}
});
}
});
The first time I update the AlertDialog message (OnConnectionStarting event) everything works fine, but the second time I got android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
What could be happening here?
Replace with
interactor = new BluetoothInteractor(getActivity(), new OnBluetoothStatusChangedListener() {
#Override
public void OnConnectionStopped() {
getActivity().runOnUiThread(new Runnable() {
#Override
void run() {
alertDialog.setMessage("Disconnected.");
}
});
}
#Override
public void OnConnectionStopping() {
getActivity().runOnUiThread(new Runnable() {
#Override
void run() {
alertDialog.setMessage("Stopping connection...");
}
});
}
#Override
public void OnConnectionStarting() {
getActivity().runOnUiThread(new Runnable() {
#Override
void run() {
alertDialog.setMessage("Connecting to device...");
}
});
}
#Override
public void OnConnectionStarted() {
getActivity().runOnUiThread(new Runnable() {
#Override
void run() {
alertDialog.setMessage("Streaming data...");
}
});
}
});

How to run code any 3000m/s in android

I write below method and i want run this method any 3000M/S
public void onShakeImage() {
Animation shake;
shake = AnimationUtils.loadAnimation(context, R.anim.shake);
arrowHelpImage.setAnimation(shake);
}
how can i do it?
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
mHandler = new Handler();
startRepeatingTask();
}
#Override
public void onDestroy() {
super.onDestroy();
stopRepeatingTask();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
onShakeImage(); //this function can change value of mInterval.
} finally {
mHandler.postDelayed(mStatusChecker, 3000);
}
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}

Timer isn't cancelled by timer.cancel()

My Timer doesn't stop running if I cancel it!
The Timer only stops if I shut down the whole app!
I don't know why the Timer is not cancelled. If I print out every try on cancelling the Timer I get hundrets of lines but the Timer does not stop!
My Class:
public class PlayActivity extends AppCompatActivity
implements View.OnClickListener, SeekBar.OnSeekBarChangeListener, MediaplayerEvent {
//region Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Initialize_Layout();
Initialize_Objects();
}
#Override
protected void onResume() {
super.onResume();
MusicService.setMediaPlayerEvent(this);
txvSongtitle.setText(serviceInterface.MP_getActualSong().getTitle());
Start_Timer();
}
#Override
protected void onPause() {
timer.cancel();
MusicService.clearMediaPlayerEvent();
super.onPause();
}
#Override
public boolean onSupportNavigateUp() {
finish();
return super.onSupportNavigateUp();
}
//endregion
//region Methods
private void Start_Timer() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (serviceInterface.MP_isPlaying()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
seekBar.setMax(serviceInterface.MP_getDuration());
seekBar.setProgress(serviceInterface.MP_getCurrentPosition());
}
});
}
else {
runOnUiThread(new Runnable() {
#Override
public void run() {
timer.cancel();
}
});
}
}
}, 0, 200);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
serviceInterface.MP_seekTo(progress);
Start_Timer();
}
}
//endregion
}
I hope you can help me!
Thanks!
I would suggest using a Thread instead of a Timer. Your Start_Timer()code would change to something like the following:
private Thread mTimerThread;
...
private void Start_Timer() {
mTimerThread = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
if (serviceInterface.MP_isPlaying()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
seekBar.setMax(serviceInterface.MP_getDuration());
seekBar.setProgress(serviceInterface.MP_getCurrentPosition());
}
});
} else {
interrupt();
}
Thread.sleep(200);
}
} catch (InterruptedException e) {
}
}
}
mTimerThread.start();
}
Threads are more efficient and lightweight and perfect for your needs. Plus, by setting the Thread to a global variable, you can make sure to call mTimerThread.interrupt(); during Android lifecycle events, such as onPause().
I hope this fixes your issue. Remember, the Java Thread is your friend!
You're creating and starting a new timer the user moves the seekbar (in onProgressChanged()). That also means you lose the reference to the old one. When isPlaying turns false, all the timers will try to cancel timer -- which only references the most recent one.

bar.setProgress(0) does not work

The following code is from Beginning Android 3, Chapter 20. When the phone is rotated, a new activity will be created and onStart() will be called, and so bar.setProgress(0) is called. However, I don't see the bar's progress is back to the beginning. Why not?
public class HandlerDemo extends Activity {
ProgressBar bar;
Handler handler=new Handler() {
#Override
public void handleMessage(Message msg) {
bar.incrementProgressBy(5);
}
};
AtomicBoolean isRunning=new AtomicBoolean(false);
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
bar=(ProgressBar)findViewById(R.id.progress);
}
public void onStart() {
super.onStart();
bar.setProgress(0);
Thread background=new Thread(new Runnable() {
public void run() {
try {
for (int i=0;i<20 && isRunning.get();i++) {
Thread.sleep(1000);
handler.sendMessage(handler.obtainMessage());
}
} catch (Throwable t) {
// just end the background thread
}
}
});
isRunning.set(true);
background.start();
}
public void onStop() {
super.onStop();
isRunning.set(false);
}
}
Try using this code
#Override
protected void onPause() {
super.onPause();
isRunning.set(false);
bar.setProgress(0);
}

Invalidate() is not happening from Activity in Timer

This is my code on Activity to Invalidate the canvas it is not invalidating. Means onDraw() is not getting called even once;
public GraphView view;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view = GraphView(this,null);
runplotTimer();
}
public void runplotTimer()
{
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
InvalidateTimer();
}
},1000,40);
}
public void InvalidateTimer()
{
this.runOnUiThread(new Runnable() {
#Override
public void run()
{
//Log.d(ALARM_SERVICE, "Timer of 40 miliseconds");
view.InvalidateGraph();
}
});
}
on View class this is method which is gettting called from Activity. other OnDraw declaration is same as required.
public void InvalidateGraph()
{
m_bCalledPlotRealTimeGraph = true;
invalidate(chanX_count1, 0, chanX_count1+7, graphheight);
}
Any help please ?
You are attempting to make changes to the View on a Timer Thread, which will not work. You need to call invalidate on the main (UI) thread:
((Activity) view.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
invalidate(chanX_count1, 0, chanX_count1+7, graphheight);
}
});
you need to Start the Timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
InvalidateTimer();
}
},1000,40);
t.start()
Instead of Timer use Handler.
class UpdateHandler implements Runnable {
#Override
public void run(){
handler.sendEmptyMessageAtTime(0, 1000);
handler.postDelayed(this, 1000);
}
}
private Handler handler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//Call your draw method
}
}
};
Inside onCreate and onResule write
if( mupdateTask == null )
mupdateTask = new UpdateHandler();
handler.removeCallbacks(mupdateTask);
Call your handler using
handler.postDelayed(mupdateTask, 100);

Categories

Resources