Я работаю над небольшим приложением, чтобы опробовать идею, которая у меня есть. Идея состоит в том, чтобы периодически обновлять пользовательский интерфейс, когда происходит какое-либо событие. В созданной мной демонстрации я обновляю ProgressDialog каждые 2 секунды в течение 15 ходов.
Проблема, с которой я столкнулся, которую я не совсем понимаю, заключается в том, что при обработке события я отправляю сообщение обработчику, который должен обновить сообщение в ProgressDialog. Однако когда это происходит, я получаю исключение, в котором говорится, что я не могу обновить пользовательский интерфейс из этого потока.
В моей активности отображается следующий код:
ProgressDialog diag;
String diagMessage = "Started loading...";
final static int MESSAGE_DATA_RECEIVED = 0;
final static int MESSAGE_RECEIVE_COMPLETED = 1;
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
diag.setMessage(diagMessage);
switch(msg.what){
case MESSAGE_DATA_RECEIVED:
break;
case MESSAGE_RECEIVE_COMPLETED:
dismissDialog();
killDialog();
break;
}
}
};
Boolean isRunning = false;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupDialog();
if(isRunning){
showDialog();
}
setContentView(R.layout.main);
}
void setupDialog(){
if(diag == null){
diag = new ProgressDialog(ThreadLoading.this);
diag.setMessage(diagMessage);
}
}
void showDialog(){
isRunning = true;
if(diag != null && !diag.isShowing()){
diag.show();
}
}
void dismissDialog(){
if(diag != null && diag.isShowing()){
diag.dismiss();
}
}
void killDialog(){
isRunning = false;
}
public void onStart(){
super.onStart();
showDialog();
Thread background = new Thread(new Runnable(){
public void run(){
try{
final ThreadRunner tr = new ThreadRunner();
tr.setOnDataReceivedListener(new ThreadRunner.OnDataReceivedListener(){
public void onDataReceived(String message){
diagMessage = message;
handler.handleMessage(handler.obtainMessage(MESSAGE_DATA_RECEIVED));
}
});
tr.setOnDataDownloadCompletedEventListener(new ThreadRunner.OnDataDownloadCompletedListener(){
public void onDataDownloadCompleted(String message){
diagMessage = message;
handler.handleMessage(handler.obtainMessage(MESSAGE_RECEIVE_COMPLETED));
}
});
tr.runProcess();
}
catch(Throwable t){
throw new RuntimeException(t);
}
}
});
background.start();
}
@Override
public void onPause(){
super.onPause();
dismissDialog();
}
Ради интереса вот код для класса ThreadRunner:
public interface OnDataReceivedListener {
public void onDataReceived(String message);
}
public interface OnDataDownloadCompletedListener {
public void onDataDownloadCompleted(String message);
}
private OnDataReceivedListener onDataReceivedEventListener;
private OnDataDownloadCompletedListener onDataDownloadCompletedEventListener;
int maxLoop = 15;
int loopCount = 0;
int sleepTime = 2000;
public void setOnDataReceivedListener(OnDataReceivedListener onDataReceivedListener){
this.onDataReceivedEventListener = onDataReceivedListener;
}
public void setOnDataDownloadCompletedEventListener(OnDataDownloadCompletedListener onDataDownloadCompletedListener){
this.onDataDownloadCompletedEventListener = onDataDownloadCompletedListener;
}
public void runProcess(){
for(loopCount = 0; loopCount < maxLoop; loopCount++){
try{
Thread.sleep(sleepTime);
onDataReceivedEventListener.onDataReceived(Integer.toString(loopCount));
}
catch(Throwable t){
throw new RuntimeException(t);
}
}
onDataDownloadCompletedEventListener.onDataDownloadCompleted("Download is completed");
}
Я что-то упустил? Логика имеет смысл для меня, и похоже, что все должно работать, я использую обработчик для обновления пользовательского интерфейса, как это рекомендуется.
Любая помощь будет оценена.
Спасибо,
Тайрон
P.S. Я разрабатываю для Android 1.5