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

后端 未结 28 3191
鱼传尺愫
鱼传尺愫 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:17

    If you simply want to invalidate (call repaint/redraw function) from your non UI Thread, use postInvalidate()

    myView.postInvalidate();
    

    This will post an invalidate request on the UI-thread.

    For more information : what-does-postinvalidate-do

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

    If you couldn't find a UIThread you can use this way .

    yourcurrentcontext mean, you need to parse Current Context

     new Thread(new Runnable() {
            public void run() {
                while (true) {
                    (Activity) yourcurrentcontext).runOnUiThread(new Runnable() {
                        public void run() { 
                            Log.d("Thread Log","I am from UI Thread");
                        }
                    });
                    try {
                        Thread.sleep(1000);
                    } catch (Exception ex) {
    
                    }
                }
            }
        }).start();
    
    0 讨论(0)
  • 2020-11-21 05:18

    In my case, the caller calls too many times in short time will get this error, I simply put elapsed time checking to do nothing if too short, e.g. ignore if function get called less than 0.5 second:

        private long mLastClickTime = 0;
    
        public boolean foo() {
            if ( (SystemClock.elapsedRealtime() - mLastClickTime) < 500) {
                return false;
            }
            mLastClickTime = SystemClock.elapsedRealtime();
    
            //... do ui update
        }
    
    0 讨论(0)
  • 2020-11-21 05:21

    You have to move the portion of the background task that updates the UI onto the main thread. There is a simple piece of code for this:

    runOnUiThread(new Runnable() {
    
        @Override
        public void run() {
    
            // Stuff that updates the UI
    
        }
    });
    

    Documentation for Activity.runOnUiThread.

    Just nest this inside the method that is running in the background, and then copy paste the code that implements any updates in the middle of the block. Include only the smallest amount of code possible, otherwise you start to defeat the purpose of the background thread.

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

    I solved this by putting runOnUiThread( new Runnable(){ .. inside run():

    thread = new Thread(){
            @Override
            public void run() {
                try {
                    synchronized (this) {
                        wait(5000);
    
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                dbloadingInfo.setVisibility(View.VISIBLE);
                                bar.setVisibility(View.INVISIBLE);
                                loadingText.setVisibility(View.INVISIBLE);
                            }
                        });
    
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Intent mainActivity = new Intent(getApplicationContext(),MainActivity.class);
                startActivity(mainActivity);
            };
        };  
        thread.start();
    
    0 讨论(0)
  • 2020-11-21 05:21

    I was facing a similar problem and none of the methods mentioned above worked for me. In the end, this did the trick for me:

    Device.BeginInvokeOnMainThread(() =>
        {
            myMethod();
        });
    

    I found this gem here.

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