igla
igla

Reputation: 115

Interact UI with the user and update UI from background thread

I have a text field(EditText) and in event onTextChanged on every change of text I send a HTTP query in a separate thread. I need to update UI from background thread.

All is fine, I know how to update UI from the background thread, but when user types text in the textfield, the keyboard is not responding on every tap(through time) and in the result not whole text is written to the textfield. It happens only when background thread updates UI.

I tried to low a priority for background thread, but nothing :(

I don't know what I'am doing wrong, help me :)

//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;
    } }

Upvotes: 0

Views: 711

Answers (2)

shem
shem

Reputation: 4712

Every device is cpu limited to certain amount of things it can do at a time. Interact with the user + update UI + send an http request it's very massive operation, especially if you doing it a lot in very short time.

Try to wait a bit for more data from user and only when he don't write anything in X time send your request in batches.

Upvotes: 0

vivek
vivek

Reputation: 4909

Do not try to change UI with background thread. Use only main thread to update any changes to UI.
Look Updating Android UI using threads

Upvotes: 2

Related Questions