I'm trying to use a spinning ProgressDialog to tell the user when the program is working. I have gotten the ProgressDialog
to show and dismiss correctly, however only when there is simple code in between the calls. I am currently initializing the ProgressDialog
within my onCreate
method, then upon a button press, the dialog will show, then a lot of code is traversed through, followed by a dismiss call. The code all executes properly, but the dialog is never shown.
public class Waves extends Activity {
private ProgressDialog pd;
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
pd = new ProgressDialog( this );
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Reading...");
pd.setCancelable(false);
setContentView( R.layout.waves );
readButton = (Button) findViewById( R.id.readButton );
readButton.setOnClickListener( new OnClickListener() {
public void onClick(View arg0) {
pd.show( );
if( myService.getState() != 3 ) {
myService.setHandler( mHandler );
myService.connect( MainMenu.previousDevice, true );
} else {
readWaves();
}
}
});
}
readWaves is shown below. At the end of readWaves is where pd.dismiss()
is called. There are many function calls from within readWaves which I will try to show without it getting too lengthy.
private void readWaves() {
if( spinnerChoice == 0 ) {
Log.i( "IN IF", "IN IF" );
// Diff Voltage
waveResults = RelayAPIModel.NativeCalls.GetWavesJava( RelayAPIModel.WAVES_V );
} else {
// Current
waveResults = RelayAPIModel.NativeCalls.GetWavesJava( RelayAPIModel.WAVES_I );
}
updateGraph();
netV1Check.setChecked( true );
netV2Check.setChecked( true );
netV3Check.setChecked( true );
vdi1Check.setChecked( true );
vdi2Check.setChecked( true );
vdi3Check.setChecked( true );
hasRead = true;
pd.dismiss();
}
The updateGraph()
call does simple cosmetics to the graphs, so I don't think the problem is there. The RelayAPIModel.NativeCalls.GetWavesJava()
call is where I think the problems arise.
GetWavesJava()
is a function written in C located in my native library. From within GetWavesJava(), there are a large number of function calls to other native C functions, as well as a large number of function calls back to the Java end of my application.
This sounds stupid, but the reason for this is that the native library in C is an existing library which needs to be used. However, it does not support Android's bluetooth capabilities, so all methods which send/receive data via Bluetooth need to be described on the Java end.
There are six total Java functions used for the I/O stream, and they are used many many times throughout the application, not just for this one call. I considered putting pd.dismiss()
in one of those functions, but it is only needed like 1% of the time those functions are called.
Does anyone know a solution to ensure that my dialog is shown before native function calls, and stops after?
This is a similar SO question but not exactly the same
EDIT :
Using the answer below, this is my code:
readButton = (Button) findViewById( R.id.readButton );
readButton.setOnClickListener( new OnClickListener() {
public void onClick(View arg0) {
pd.show( );
Thread export = new Thread() {
public void run() {
if( myService.getState() != 3 ) {
Log.i( "myService", "12222" );
myService.setHandler( mHandler );
myService.connect( MainMenu.previousDevice, true );
} else {
Log.i("myService", "32222" );
readWaves();
Log.i( "myService", "42222" );
}
mHandler.obtainMessage(MainMenu.READ_FINISHED );
}
};
export.start();
}
});
The Log( 42222 )
is never reached. The spinner does appear, but the program crashes and restarts in a few seconds. I have added .sendToTarget()
in the mHandler.obtainMessage()
line, but this results in no spinner appearing, and the program crashing.
EDIT 2 :
I would also like to add that the readWaves
function uses existing running threads to execute. I'm not sure if that makes any difference
EDIT 3 :
Here I updated the second code block from the initial submission. Using this code, the progress dialog never shows itself. The code executes as all code involving the ProgressDialog
was not there at all.
private void readWaves() {
if( spinnerChoice == 0 ) {
Log.i( "IN IF", "IN IF" );
// Diff Voltage
waveResults = RelayAPIModel.NativeCalls.GetWavesJava( RelayAPIModel.WAVES_V );
} else {
// Current
waveResults = RelayAPIModel.NativeCalls.GetWavesJava( RelayAPIModel.WAVES_I );
}
pd.dismiss();
updateGraph();
netV1Check.setChecked( true );
netV2Check.setChecked( true );
netV3Check.setChecked( true );
vdi1Check.setChecked( true );
vdi2Check.setChecked( true );
vdi3Check.setChecked( true );
hasRead = true;
}
EDIT 4:
This is my most recent code. The ProgressDialog shows up where I want it to but the spinner does not spin. I have tried replacing pd.dismiss()
with pd.hide()
and putting pd.dismiss()
later in the code but this results in the dialog always staying on the screen. And since .setCancelable(false)
is used I can never back out of it. I have also taken the declaration of pd
outside of the onClickListener because I cannot pass the argument this
to the ProgressDialog
within the OnClickListener
. I don't remember what I can pass to it to make it work, I tried getApplicationContext()
, ClassName.java
and ClassName.class
but none of them worked.
readButton = (Button) findViewById( R.id.readButton );
final ProgressDialog pd = new ProgressDialog( this );
readButton.setOnClickListener( new OnClickListener() {
public void onClick(View arg0) {
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Reading...");
pd.setCancelable(false);
pd.show( );
Thread export = new Thread() {
public void run() {
if( myService.getState() != 3 ) {
Log.i( "myService", "12222" );
myService.setHandler( mHandler );
myService.connect( MainMenu.previousDevice, true );
} else {
runOnUiThread(new Runnable() {
public void run() {
readWaves();
}
});
}
mHandler.obtainMessage(MainMenu.READ_FINISHED ).sendToTarget();
pd.dismiss();
}
};
export.start();
EDIT 5: Trying to get the spinner to appear for the if
statement:
readButton = (Button) findViewById( R.id.readButton );
readButton.setOnClickListener( new OnClickListener() {
public void onClick(View arg0) {
final ProgressDialog pd = new ProgressDialog( Waves.this );
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Reading...");
pd.setCancelable(false);
pd.show( );
Thread export = new Thread() {
public void run() {
if( myService.getState() != 3 ) {
Log.i( "myService", "12222" );
myService.setHandler( mHandler );
runOnUiThread( new Runnable() {
public void run() {
myService.connect( MainMenu.previousDevice, true );
}
});
} else {
runOnUiThread(new Runnable() {
public void run() {
readWaves();
}
});
}
mHandler.obtainMessage(MainMenu.READ_FINISHED ).sendToTarget();
pd.dismiss();
}
};
export.start();