Reputation: 51
My program is structured as followed. I have the following main activity. This activity will create a "Determine Location" object. This Determine location object will take in a few parameters. Amongst them is a handler to pass the results along to. In the following I pass in threadHandler which is of type MyThreadHandler (an extension of handler). This DetermineLocation object implements runnable and in the run method it queries the GPS and passes the results along in a message to threadHandler (passed into the DetLoc object). The threadHandler instance takes in a textview object upon creation (this is the text view to update)
For debugging purposes I have disabled the GPS update feature and only had DetLoc's run method pass a random number. This however is still crashing my program.
The crash mainly happens while pushing a lot of input to the device (such as pressing the screen in multiple places really fast). This is a thread issue for sure but I do not see why.
MAIN:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
threadModifiedText = (TextView) findViewById(R.id.thread_modified_text);
threadHandler = new MyHandler(threadModifiedText);
//Start up the DetermineLocation thread. This thread will query the GPS every N milliseconds.
// then push the results over hte network if at all possible
DetermineLocation detLoc = new DetermineLocation(this, threadHandler, 3000);
Thread detLocThread = new Thread(detLoc);
detLocThread.start();
}
ALSO MAIN:
class MyHandler extends Handler{
private TextView threadModifiedText;
public MyHandler(TextView tv) {
threadModifiedText = tv;
}
public void handleMessage(Message msg) {
// whenever the Thread notifies this handler we have
// only this behavior
threadModifiedText.setText((CharSequence)msg.obj);
}
}
DetermineLocation class (as you can see the GPS stuff has been commented out and its still crashing):
public class DetermineLocation implements Runnable {
private int updateInterval;
private int provider=3;
private Handler threadHandler;
private Context c;
public final int GPS_ONLY=1;
public final int NETWORK_ONLY=2;
public final int ANY_AVAILABLE=3;
public DetermineLocation(Context c, Handler h, int ui) {
this.c = c;
this.updateInterval = ui;
this.threadHandler = h;
}
public void changeProvider(int providerConst) {
if(providerConst <=3 && providerConst >= 1)
provider = providerConst;
}
public void changeUpdateInterval(int updateIntervalMS) {
if(updateIntervalMS >= 0)
this.updateInterval = updateIntervalMS;
}
@Override
public void run() {
Message m = new Message();
//LocationManager locationManager = (LocationManager)c.getSystemService(Context.LOCATION_SERVICE);
//Location loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
while(true) {
CharSequence cs = Math.random() + "\r\n"; //+ loc.getLatitude() + " " + loc.getLongitude();
m.obj = cs;
threadHandler.sendMessage(m);
try {
Thread.sleep(updateInterval);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Upvotes: 0
Views: 577
Reputation: 38707
You appear to be instantiating just the one Message
, writing it continuously on your background thread, and then reading it continuously from your UI thread, with no synchronization. It's not surprising things go boom.
You can fix this either by using Message.obtain()
for each message you send across the thread boundary, or you can make your life a whole lot simpler by using an AsyncTask
.
With an AsyncTask
you don't need any Handlers
or Runnables
... it makes threading as simple as it ought to be.
Upvotes: 3