2つのボタン(接続とデータの要求)を持つAndroidアプリケーション(Javaで記述)があります。
各ボタンをクリックすると、タスクが実行され、進行状況ダイアログが表示され、タスクがどれだけ完了したかが示されます。
進行状況ダイアログを表示するために、各ボタンがクリックされると、タスクはスレッド上で実行されます。
接続ボタンには、スレッド上で実行するという1つのタスクしかありません。ただし、データ要求ボタンは2つのタスクを実行します。接続ボタンに似たスレッドの最初のタスクだけでなく、スレッドの最初のタスクprogThreadの終了後に実行する必要がある2番目のタスクrefreshInfo()も実行します。
private Button connectButton;
private Button requestDataButton;
private ProgressDialog connectionDialog;
private ProgressDialog requestDataDialog;
private ProgressThread progThread;
private int currentDialog;
public void connectClick(View view) //When the connect button is clicked
{
performAction(1); //Run the thread to perform the action
}
public void requestDownloadClick(View view) //When the request data button is clicked
{
performAction(2); //Run the thread to perform the action
refreshInfo(); //Do something else
}
private void performAction(int type)
{
currentDialog = type;
showDialog(type);
try
{
progThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
ここでの重要なメソッドはperformAction(int type)です。基本的に、 progThreadの実行が終了するまでこのメソッドを完了させたくありません。
ご覧のとおり、progThread.join()を実行して、 progThreadの実行が終了するまでメソッドが続行されないようにしましたが、 progThreadには進行状況ダイアログの表示が含まれるため、 progThread.join()を実行すると、進行状況ダイアログが表示されないようです。現在ボタンをクリックすると、最初のタスクが実行されますが、ダイアログは最後にのみ点滅します。
スレッドを実行する方法を考えて、進行状況ダイアログを通常どおりに表示してから、2番目のメソッド(存在する場合)を実行することはできますか?
必要な場合に備えて、以下のスレッドコードを含めました。
private class ProgressThread extends Thread
{
final static int DONE = 0;
final static int RUNNING = 1; // Class constants defining state of the thread
private Handler progressHandler;
int mState;
int total;
ProgressThread(Handler _handler) // Constructor with an argument that specifies Handler on main thread to which messages will be sent by this thread.
{
progressHandler = _handler;
}
public void run() // Invoked automatically when the Thread starts.
{
mState = RUNNING;
updateProgressBar();
connectButton = (Button) findViewById(R.id.btnConnect);
requestDataButton = (Button) findViewById(R.id.btnRequestDownload);
while (mState == RUNNING)
{
if (currentDialog == 1)
{
try
{
doSomething();
if (something)
{
setState(DONE);
total = 100;
updateProgressBar();
removeDialog(1);
connectButton.setEnabled(false);
}
else
{
total = total + 20;
if (something has reached a limit)
{
setState(DONE);
total = 0;
updateProgressBar();
removeDialog(1);
}
}
updateProgressBar();
}
catch (Exception e)
{
}
}
if (currentDialog == 2)
{
try
{
doSomething();
total = 10;
updateProgressBar();
doSomething();
total = 70;
updateProgressBar();
if (something) //If the download info has not been got
{
setState(DONE);
total = 0;
updateProgressBar();
removeDialog(2);
runOnUiThread(new Runnable()
{
public void run()
{
connectButton.setEnabled(true);
requestDataButton.setEnabled(true);
}
});
}
else
{
total = 100;
updateProgressBar();
setState(DONE);
removeDialog(2);
runOnUiThread(new Runnable()
{
public void run()
{
requestDataButton.setEnabled(false);
}
});
}
}
catch (Exception e)
{
removeDialog(2);
setState(DONE);
runOnUiThread(new Runnable()
{
public void run()
{
connectButton.setEnabled(true);
requestDataButton.setEnabled(true);
}
});
}
}
}
}
// Set current state of thread (use state=ProgressThread.DONE to stop thread)
public void setState(int state)
{
mState = state;
}
public void updateProgressBar()
{
Message msg = progressHandler.obtainMessage(); // Send message (with current value of total as data) to Handler on UI thread so that it can update the progress bar
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
progressHandler.sendMessage(msg);
}
}
final Handler handler = new Handler() // Handler on the main (UI) thread that will receive messages from the second thread and update the progress.
{
public void handleMessage(Message msg)
{
int total = msg.getData().getInt("total"); // Get the current value of the variable total from the message data and update the progress bar
switch (currentDialog)
{
case 1 :
connectionDialog.setProgress(total);
break;
case 2 :
requestDataDialog.setProgress(total);
break;
}
}
};
protected Dialog onCreateDialog(int id)
{
switch (currentDialog)
{
case 1 :
connectionDialog = new ProgressDialog(this);
connectionDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
connectionDialog.setMax(100);
connectionDialog.setProgress(0);
connectionDialog.setMessage("Connecting To The Device");
progThread = new ProgressThread(handler);
progThread.start();
return connectionDialog;
case 2 :
requestDataDialog = new ProgressDialog(this);
requestDataDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
requestDataDialog.setMax(100);
requestDataDialog.setProgress(0);
requestDataDialog.setMessage("Requesting Download Data");
progThread = new ProgressThread(handler);
progThread.start();
return requestDataDialog;
default :
return null;
}
}