Hello everyone,
I’ve run into a problem that I’m not sure how to deal with as a novice Android developer. Whenever I call the GetValueThread to retrieve a value from an ultrasonic sensor from the Photon, the UI thread continues and attempts to update the TextView that I would like to contain the sensor value.
MainActivity.java:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import io.particle.android.sdk.devicesetup.ParticleDeviceSetupLibrary;
public class MainActivity extends Activity {
private Button mGetCurrentReadingButton;
public TextView mCurrentReadingValue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ParticleDeviceSetupLibrary.init(this.getApplicationContext(), MainActivity.class);
// Declare and assign our buttons and text
mGetCurrentReadingButton = (Button) findViewById(R.id.getCurrentReadingButton);
mCurrentReadingValue = (TextView) findViewById(R.id.currentReadingValue);
final View.OnClickListener getResult = new View.OnClickListener() {
@Override
public void onClick(View v) {
GetValueThread thread = new GetValueThread();
thread.setName("GetValueThread");
thread.start();
try {
thread.join();
int result = thread.getResultCode();
displayCurrentValue(result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
mGetCurrentReadingButton.setOnClickListener(getResult);
}
private void displayCurrentValue(int result){
mCurrentReadingValue.setText(result + " cm");
Log.d("mCurrentReadingValue", result + " cm");
Log.d("Result", "Executing the previous line of code before a result has been captured from Photon.");
}
}
And the GetValueThread.java:
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.IOException;
import io.particle.android.sdk.cloud.ParticleCloudException;
import io.particle.android.sdk.cloud.ParticleCloudSDK;
import io.particle.android.sdk.cloud.ParticleDevice;
import io.particle.android.sdk.utils.Async;
import static io.particle.android.sdk.utils.Py.list;
public class GetValueThread extends Thread {
public int resultCode;
@Override
public void run() {
try {
getValue();
getResultCode();
} catch (ParticleCloudException | ParticleDevice.VariableDoesNotExistException | IOException e) {
e.printStackTrace();
}
}
public void getValue() throws ParticleCloudException, IOException, ParticleDevice.VariableDoesNotExistException {
try {
final ParticleDevice myDevice = ParticleCloudSDK.getCloud().getDevice("trailblazer01");
Async.executeAsync(myDevice, new Async.ApiWork<ParticleDevice, Integer>() {
public Integer callApi(@NonNull ParticleDevice particleDevice)
throws ParticleCloudException, IOException {
try {
resultCode = myDevice.callFunction("range1", list("Get range 1"));
Log.d("aString", "Result of calling range1: " + resultCode);
return resultCode;
} catch (ParticleDevice.FunctionDoesNotExistException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onSuccess(@NonNull Integer s) {
Log.d("Result", resultCode + " cm");
}
@Override
public void onFailure(@NonNull ParticleCloudException e) {
Log.e("Result", "Something went wrong making an SDK call: ", e);
}
});
} catch (ParticleCloudException e) {
e.printStackTrace();
}
}
public int getResultCode() {
return resultCode;
}
}
From above, when running the code, I get the debug message: “Executing the previous line of code before a result has been captured from Photon.” before I get the debug message from GetValueThread displaying the data retrieved.
How can I ensure that the TextView is only updated after the GetValueThread has had time to run. Also note, the time taken for the thread appears to vary slightly such that I’d prefer to avoid a static delay (e.g. 2000 ms) to wait for it to complete.
Thanks!