在从Thread更新我的UI时苦苦挣扎

时间:2013-08-14 01:37:38

标签: android multithreading loops android-asynctask handler

我已经尝试过AsyncTask,Handler和一个简单的线程来实现我想要做的事情,但我无法让它们中的任何一个工作,下面是我需要用来更新我的UI的逻辑... < / p>

public class GameProcessor extends Thread {

@Override
public void run() {

    for (Integer integer : sequence) {

        //set button state to pressed
        Console.getBottomLeft().getButton().setBackgroundResource(R.drawable.button_focused);

        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //set button state to un-pressed

        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    try {
        sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


}

}

请不要回复,你不能从主线程的任何地方更新UI,我已经知道这一点,并且需要一个解决方案来解决如何在同时更新UI时从后端循环某些值。据我所知,AsyncTask和Handler无济于事。

非常感谢任何帮助!

5 个答案:

答案 0 :(得分:3)

如果您了解UI线程,为什么不:

runOnUiThread(new Runnable() {
    public void run() {
        //set button state to un-pressed or pressed.. or whatever you want..
    }
});

我不明白你的问题

答案 1 :(得分:0)

    If you want to loop through some valuse, while updating the UI at the same time, then you may consider using AsyncTask and may use this feature:

    protected void onProgressUpdate(Integer... progress) {
             setProgressPercent(progress[0]);
         }

    And from :
    protected Long doInBackground(URL... urls) {
                 calculate value
                 publishProgress(value);
              return totalSize;
         }

    This will keep on updating UI thread with intermediate values you send.

    In case you already know this and have tried and it does not solve your purpose, am sorry :)

or you can try this:

public void run(){

        Console.post(new Runnable() {
            public void run() {
                Console.getBottomLeft().getButton().setBackgroundResource(R.drawable.button_focused);
            }
        });
    }

答案 2 :(得分:0)

在Activity(mHandler)中创建一个成员Handler对象。每当您想要从其他线程更新UI时,请致电

mHandler.post(new Runnable(){
    public void run(){
        //update the button state
    }
});

Handler将在UI线程中为您调用此run()方法。

这是简化的。您可能希望将Runnables创建为成员变量,这样您就不会一遍又一遍地重新创建相同的Runnable。

答案 3 :(得分:0)

为了更新您的UI线程,您可以使用处理程序。这是使用AsyncTask和Handler的简单示例:

    private static final String MESSAGE_KEY = "com.example.mypackage.MSGKEY";
    private static final int MESSAGE_AUTHENTICATING = 0;
    private static final int MESSAGE_AUTHENTICATED = 1;

    /**
     * This handler will update UI 
     * 
     */
    private final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.getData().getInt(MESSAGE_KEY)) {
            case MESSAGE_AUTHENTICATING:
                hashstream_stream.setVisibility(View.GONE);
                hashstream_progress.setVisibility(View.VISIBLE);
                break;
            case MESSAGE_AUTHENTICATED:
                hashstream_stream.setVisibility(View.VISIBLE);
                hashstream_progress.setVisibility(View.GONE);
                break;
            default:
                break;

            }
        }
    };

    /**
    * This method should be used to update UI thread.
    * 
    * @param value
    */
    private void postMessage(int value) {
        Message msgObj = handler.obtainMessage();
        Bundle bundle = new Bundle();
        bundle.putInt(MESSAGE_KEY, value);
        msgObj.setData(bundle);
        handler.sendMessage(msgObj);
    }

    /**
     * AsyncTask Helper class as network op
     * 
     * 
     */
    private class StreamHashTagTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            //Do actual operation in here

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            postMessage(MESSAGE_AUTHENTICATED);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            postMessage(MESSAGE_AUTHENTICATING);
        }

        /**
         * If you need to update progress override onProgressUpdate() method.
         * Since I am indeterminate using progress bar as authentication time
         * cannot be calculated , I don't need update here
         */

    }

答案 4 :(得分:0)

你试过吗?

instanceOfActivity.runOnUiThread(new Runnable(){
    @Override
    public void run() {
        Console.getBottomLeft().getButton().setBackgroundResource(R.drawable.button_focused);
    }
});

但在这种情况下,我不建议您在另一个对象中使用活动。

请使用上面的界面:

public interface INotifyChange {
     void notify(object value); // Example: void notify(int progress);
}

在您调用 GameProcessor

的活动中
INotifychange mNotifier;

mNotifier = new INotifyChange() {
    @Override
    public void notify(object value) {
        runOnUiThread(new Runnable(){
            @Override
            public void run() {
                //You can update your UI here.
            }
        });
    }
};

//你的 GameProcessor

private INotifyChange mNotifier;
public GameProcessor(INotifyChange aNotifier) {
    mNotifier = aNotifier;
}

//您想要更新UI的位置,请调用

mNotifier.notify(value);