Reputation: 907
I just begun with a simple thread handler program on Android. The code works. The only part is on how to shut down the handler. I am trying in vain to close the handler onPause() but it simply keeps running. Any suggestions?
Here is the code: My Main Activity thread:
package com.test.prog;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class AndroidThreadProgv1Activity extends Activity {
private Handler DataHandler;
private DataUpdater du;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* Initialize handler to allow UI updating in other threads */
DataHandler = new Handler();
startDataUpdater();
}
public void onPause(){
super.onPause();
du.stopConnection();
}
private void startDataUpdater(){
System.out.println("In startDataUpdater");
du = new DataUpdater(DataHandler,(TextView) findViewById(R.id.textView1));
du.start();
}
}
DataUpdater.java:
package com.test.prog;
import java.io.IOException;
import android.os.Handler;
import android.os.Looper;
import android.widget.TextView;
/*
* Data updater thread. Updates the display with the response.
*/
public class DataUpdater extends Thread{
/*Handler for the UI update*/
private Handler dataRefreshHandler;
/*The UI text displaying the data*/
private TextView dataLabel;
/*data value*/
private int data = 0;
/*data update rate in ms*/
private static final int dataUpdateRate = 2000;
private boolean stoppedFlag= false;
public DataUpdater(Handler handler, TextView tv){
this.dataRefreshHandler = handler;
this.dataLabel = tv;
}
public void stopConnection()
{
if(this.dataRefreshHandler != null) {
this.dataRefreshHandler.removeMessages(data); // Remove a delayed message
System.out.println("In stopConnection");
/*
if(!stoppedFlag){
this.dataRefreshHandler.getLooper().quit(); // Warning
stoppedFlag = true;
}
*/
}
}
@Override
public void run(){
try {
while(true){
System.out.println("In run");
data = data + 1;
updateData();
Thread.sleep(dataUpdateRate);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
/*
* Calls the UI Handler and updates the display
*/
private void updateData(){
dataRefreshHandler.post(new Runnable() {
public void run() {
if(data==0)
{
dataLabel.setText("Value not known");
}
else
{
System.out.println("In update");
dataLabel.setText("Value="+data);
}
}
});
}
}
Upvotes: 1
Views: 4406
Reputation: 23171
Your "run" method in dataUpdater has a while(true)
loop. You never check for any exit condition so it will never stop. What you could do is include a volatile
flag in DataUpdater (initially set to true) and have stopConnection
set it to false. Your while loop in run
can check that flag instead of just looping infinitely.
To make sure your DataUpdater is running whenever your activity is running:
Move the call to startDataUpdater();
from onCreate
to onResume
(Android always calls onResume after onCreate so this will ensure that you are always calling startDataUpdater on creation as well as on resuming after pause).
Change your run method in DataUpdater to look like this:
public void run(){
isRunning = true; // isRunning should be declared as a "private volatile boolean"
try {
while(isRunning){
System.out.println("In run");
data = data + 1;
updateData();
Thread.sleep(dataUpdateRate);
}
}
Upvotes: 2
Reputation: 4251
You can make user of the Looper, instead of using while(1) which is CPU hogger. For looping back , you can post the messages back to same handler in the looper. For stopping when ever you want just post the runnable Looper.myLooper.stop() in the run() method of the runnable to the looper.
Looper is more efficient than the While(true)
Upvotes: 2