简体   繁体   中英

What's the difference between view.post() and GlobalScope.launch(Dispatchers.Main)?

Actually I met a problem with dynamically adjusting the textview gravity which depends on its line count.

I read this article , but I just don't really understand the difference about threading techniques, just like textview.post() , runOnUiThread{} , GlobalScope.launch(Dispatchers.Main) , Thead{}.start() .

TLDR, short question is " Why the codes below should be run in the post scope? "

private fun setText(text : String) {
    textView.text = text

    textView.post {
        if (textView.lineCount > 1) {
            textView.gravity = Gravity.START
        }else {
            textView.gravity = Gravity.CENTER
        }
    }
}

and another short question is " Why it doesn't work in the GlobalScope.launch(Dispatchers.Main)? "

This is my try:

private fun setText(text : String) {
    textView.text = text

    GlobalScope.launch(Dispatchers.Main) {
        if (textView.lineCount > 1) {
            textView.gravity = Gravity.START
        }else {
            textView.gravity = Gravity.CENTER
        }
    }
}

I tried to put it into GlobalScope.launch(Dispatchers.Main), but it sometimes works and sometimes doesn't work. Also, I tried to make it without textView.post() , and it just doesn't work. The source code of getLineCount() doesn't seem to be async operation?

Any suggestion is welcome, thanks for everything.

1. Difference between view.post() and GlobalScope.launch(Dispatchers.Main)?

The "post" methods ( View.post(...) , View.postDelayed(...) , etc.) put the Runnable to queue which is processed by UI/Main thread. The point here is to do all UI updates from a single thread.

What GlobalScope.launch(Dispatchers.Main) does is that (in addition to aforementioned post methods) it allows you to use all the features provided by Coroutines : for example you can suspend the code execution without blocking the Main/UI thread. That means that you can code in imperative style which comes handy for more complicated scenarios, like updating UI in loop each few milliseconds . You just suspend the loop for as long as you need. With post methods you would have to call View.post(...) with new Runnable every few ms to update the UI. For more details read the whole Guide to UI programming with coroutines .

2. "... it sometimes works and sometimes doesn't..."

I believe, that the reason why your implementation "sometimes works and sometimes doesn't" might be, that you need to call all UI manipulation methods from within the UI (aka Main) thread; meaning that your textView.text = text should also be part of your post block.

private fun setText(text : String) {
    textView.post {
        textView.text = text
        if (textView.lineCount > 1) {
            textView.gravity = Gravity.START
        }else {
            textView.gravity = Gravity.CENTER
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM