从具有线程的事件更新UI

时间:2010-03-26 08:48:52

标签: android

我正在开发一个小应用程序来尝试我的想法。我们的想法是在发生某种事件时定期更新UI。在我创建的演示中,我每2秒更新一次ProgressDialog,持续15回合。

我遇到的问题,我不太明白,当处理一个事件时,我会向处理程序发送一条消息,该处理程序应该更新ProgressDialog中的消息。但是,当发生这种情况时,我得到一个异常,表明我无法从该线程更新UI。

以下代码出现在我的活动中:

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");
}

我错过了什么吗?逻辑对我来说很有意义,看起来一切都应该有效,我正在使用处理程序来更新UI,就像推荐的那样。

任何帮助将不胜感激。

谢谢, 泰龙

P.S。我正在为Android 1.5开发

1 个答案:

答案 0 :(得分:0)

我发现了问题。在将我的代码与其他非常相似的代码进行比较后,发现了以下小问题:

  

处理程序的的handleMessage (handler.obtainMessage(MESSAGE_RECEIVE_COMPLETED));

实际应该是:

  

处理程序的的sendMessage (handler.obtainMessage(MESSAGE_RECEIVE_COMPLETED));

希望有人发现这很有用,并从我的错误中学习:)

此致 泰龙