与用户交互UI并从后台线程更新UI

时间:2013-05-30 12:15:26

标签: java android multithreading user-interface

我有一个文本字段(EditText),在事件onTextChanged中,每次更改文本时,我都会在单独的线程中发送HTTP查询。我需要从后台线程更新UI。

一切都很好,我知道如何从后台线程更新UI,但是当用户在文本字段中键入文本时,键盘在每次点击时都没有响应(通过时间),结果不是全文写入文本域。它仅在后台线程更新UI时发生。

我试图降低后台线程的优先级,但没有:(

我不知道我做错了什么,请帮帮我:)。

//Create a background thread on UI thread
ex = new ExampleThread2(this, text);
ex.start();

// ExampleThread2.java

public class ExampleThread2 extends Thread implements Handler.Callback {

    private static final String LOG_TAG = ExampleThread2.class.getSimpleName();

    Semaphore s = new Semaphore(0);

    public static final int BEGIN_TASK = 1; 
    public static final int END_TASK = 2; 

    private boolean running = true;



    public Handler mLoaderHandler;
    public TModel mLoaderCallback;

    public ExampleThread2(TModel callback, String text) {
         this.mLoaderCallback = callback;
    }

    void sendMessage(int message){
        Message msg = mLoaderHandler.obtainMessage();
        msg.what = message;
        mLoaderHandler.sendMessage(msg);
    }

    @Override
    public void run(){

        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

        //HandlerThread myHandlerThread = new HandlerThread("MyHandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
        //myHandlerThread.start();

        this.mLoaderHandler = new Handler(Looper.getMainLooper(), this);



        do {
            sendMessage(BEGIN_TASK); //Updates UI
            start2(); //main work
            sendMessage(END_TASK); //Updates UI


                try {
                    s.acquire();
                    if(s.availablePermits() > 0){
                        s.acquire(s.availablePermits());
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace(); 
                }

        } while(running);



        // Tell the handler thread to quit
        //myHandlerThread.quit();
    }

    @Override
    public boolean handleMessage(final Message msg) {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        switch (msg.what) {
           case BEGIN_TASK:

                mLoaderHandler.post(new Runnable() {
                    @Override
                    public void run() {
                         updateUI();
                    }
                });

                break;
            case END_TASK:

                mLoaderHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateUI();
                    }
                });

                break;
    } }

2 个答案:

答案 0 :(得分:2)

不要尝试使用后台线程更改UI。仅使用主线程更新UI的任何更改 看Updating Android UI using threads

答案 1 :(得分:0)

每台设备的CPU都限制在一次可以执行的某些事情上。 与用户交互+更新用户界面+发送http请求非常大量操作,特别是如果你在很短的时间内做了很多。

尝试等待来自用户的更多数据,并且只有当他在X时间内没有写任何内容时才会批量发送您的请求。