Hey guys I am having an issue that a method I am trying to run every thirty seconds is causing my toggle button to crash. My goal is to send data to a database based on the button click, and while the toggle button is on to continue sending that data through a method every thirty seconds. When I click the button, I get the Unfortunately error and the app crashes.
To save the length of this post, this button to send the data only one time works fine:
uploadOnce.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view) {
try {
SendCode(socket);
}catch(Exception e){
String stackTrace = Log.getStackTraceString(e);
sendEmail(stackTrace);
}
}
});
Notice that the above button click uses the SendCode method and it works correctly.
The error that I am having is using that same method with a timer on it, like so:
This is the toggle button onClick:
toggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
if (toggle.isChecked()) {
makeToast("On");
sendForever();
}
}catch (Exception e){
String stackTrace = Log.getStackTraceString(e);
sendEmail(stackTrace);
}
}
});
If I take the sendForever() method out, the toggle button works fine as expected.
This is the sendForever method in the toggle button:
public void sendForever(){
if(toggle.isChecked()) {
while (toggle.isChecked()) {
try {
new Handler().postDelayed(new Runnable() {
// Runs a timer to send code to database every 30 seconds
@Override
public void run() {
try {
SendCode(socket);
} catch (Exception e2) {
String stackTrace = Log.getStackTraceString(e2);
sendEmail(stackTrace);
}
}
}, 30000);
} catch (Exception e) {
String stackTrace = Log.getStackTraceString(e);
sendEmail(stackTrace);
}
sendForever();
}
}
}
So the goal is that when this method is called, it checks to see if the toggle button is in the "ON" state, then while it is on it will run the SendCode method (which works fine in the button to send it only once) then wait 30 seconds. After the 30 seconds is over I am going to call the method again until the toggle button is hit again and breaks the loop.
My problem I am having is that I am using this on an OBD2 sensor in my car, and it is not hitting the sendEmail methods to shoot me a stacktrace of the error, so I am not able to post the stacktrace as of now.
If anybody has any advice on what is going wrong or what I can look at to fix this, it would be greatly appreciated. Once again, sorry for not being able to put the stacktrace up right now, I will edit the post if I am able to acquire it.
You call sendForever()
from the method itself (in a loop, even). That will result in a stack overflow as the recursion is limited only by the toggle condition. Just remove the recursive call, since you already have the loop handling the repetition (well, that would solve the stack overflow, but see next paragraph for further issues).
Note also that you have a blocking task running in the UI thread. Since you block the UI thread, the toolkit will have no chance to make the button not toggled anymore, essentially locking up your application. Simplest is probably checking the condition after the previous sending is done, and schedule a new one if needed.
A side note: It's needless to do an if (toggle.isChecked())
check in sendForever()
since you have the same condition in the while loop.