Android “Only the original thread that created a view hierarchy can touch its views.”

后端 未结 28 3188
鱼传尺愫
鱼传尺愫 2020-11-21 04:44

I\'ve built a simple music player in Android. The view for each song contains a SeekBar, implemented like this:

public class Song extends Activity implement         


        
相关标签:
28条回答
  • 2020-11-21 05:31

    I use Handler with Looper.getMainLooper(). It worked fine for me.

        Handler handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                  // Any UI task, example
                  textView.setText("your text");
            }
        };
        handler.sendEmptyMessage(1);
    
    0 讨论(0)
  • 2020-11-21 05:31

    If you do not want to use runOnUiThread API, you can in fact implement AsynTask for the operations that takes some seconds to complete. But in that case, also after processing your work in doinBackground(), you need to return the finished view in onPostExecute(). The Android implementation allows only main UI thread to interact with views.

    0 讨论(0)
  • 2020-11-21 05:31

    In my case, I have EditText in Adaptor, and it's already in the UI thread. However, when this Activity loads, it's crashes with this error.

    My solution is I need to remove <requestFocus /> out from EditText in XML.

    0 讨论(0)
  • 2020-11-21 05:32

    Kotlin coroutines can make your code more concise and readable like this:

    MainScope().launch {
        withContext(Dispatchers.Default) {
            //TODO("Background processing...")
        }
        TODO("Update UI here!")
    }
    

    Or vice versa:

    GlobalScope.launch {
        //TODO("Background processing...")
        withContext(Dispatchers.Main) {
            // TODO("Update UI here!")
        }
        TODO("Continue background processing...")
    }
    
    0 讨论(0)
  • 2020-11-21 05:33

    My solution to this:

    private void setText(final TextView text,final String value){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                text.setText(value);
            }
        });
    }
    

    Call this method on a background thread.

    0 讨论(0)
  • 2020-11-21 05:34

    Usually, any action involving the user interface must be done in the main or UI thread, that is the one in which onCreate() and event handling are executed. One way to be sure of that is using runOnUiThread(), another is using Handlers.

    ProgressBar.setProgress() has a mechanism for which it will always execute on the main thread, so that's why it worked.

    See Painless Threading.

    0 讨论(0)
提交回复
热议问题