【发布时间】:2012-12-28 18:44:48
【问题描述】:
我正在尝试使用旋转的 ProgressDialog 来告诉用户程序何时运行。我已经让ProgressDialog 正确显示和关闭,但是只有在调用之间有简单的代码时。我目前正在我的onCreate 方法中初始化ProgressDialog,然后在按下按钮时,将显示对话框,然后遍历大量代码,然后是关闭调用。代码全部正常执行,但对话框从未显示。
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 如下所示。在 readWaves 的末尾是调用 pd.dismiss() 的地方。在 readWaves 中有很多函数调用,我将尝试展示它们,但不会太冗长。
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();
}
updateGraph() 调用对图表做了简单的修饰,所以我认为问题不存在。 RelayAPIModel.NativeCalls.GetWavesJava() 电话是我认为问题出现的地方。
GetWavesJava() 是一个用 C 语言编写的函数,位于我的本地库中。在 GetWavesJava() 中,有大量对其他本机 C 函数的函数调用,以及对我的应用程序 Java 端的大量函数调用。
这听起来很愚蠢,但原因是 C 中的本机库是需要使用的现有库。但是,它不支持Android的蓝牙功能,所以所有通过蓝牙发送/接收数据的方法都需要在Java端进行描述。
总共有六个 Java 函数用于 I/O 流,它们在整个应用程序中被多次使用,而不仅仅是这一次调用。我考虑将pd.dismiss() 放在其中一个函数中,但仅在调用这些函数的 1% 时才需要它。
有谁知道确保我的对话框在本机函数调用之前显示并在之后停止的解决方案?
This is a similar SO question but not exactly the same
编辑:
使用下面的答案,这是我的代码:
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();
}
});
永远无法到达Log( 42222 )。微调器确实出现了,但程序会在几秒钟内崩溃并重新启动。我在mHandler.obtainMessage() 行中添加了.sendToTarget(),但这会导致没有微调器出现,并且程序崩溃。
编辑 2:
我还要补充一点,readWaves 函数使用现有的正在运行的线程来执行。我不确定这是否有什么不同
编辑 3:
这里我更新了最初提交的第二个代码块。使用此代码,进度对话框永远不会显示自己。代码执行时,涉及ProgressDialog 的所有代码根本不存在。
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;
}
编辑 4:
这是我最近的代码。 ProgressDialog 显示在我想要的位置,但微调器不旋转。我尝试将pd.dismiss() 替换为pd.hide() 并将pd.dismiss() 稍后放入代码中,但这会导致对话框始终停留在屏幕上。而且由于使用了.setCancelable(false),我永远无法退出它。我还在 onClickListener 之外声明了pd,因为我无法将参数this 传递给OnClickListener 内的ProgressDialog。我不记得我可以传递给它什么让它工作,我尝试了getApplicationContext()、ClassName.java 和ClassName.class,但它们都没有工作。
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();
编辑 5: 试图让微调器出现在 if 语句中:
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();
【问题讨论】:
-
使用您的第二个版本,我有几个问题: 1. readWaves() 是否以任何方式更新 UI,或触摸任何 UI 树对象? 2.您是否将您的progressDialog 声明为final? 3. 为什么 pd.dismiss() 在 readWaves() 和末尾,而不是在你的 Thread 的 run() 的 AFTER readWaves() 行中?
-
其实这一切都归结为 updateGraph();做。它有什么作用?
-
@varevarao 看看我的第三次编辑。所有 UI 都在
updateGraph()内更新,而不是在readWaves()内更新。 -
宾果游戏,等一下。我可能已经解决了你的问题。
标签: android android-ndk java-native-interface progressdialog