我们如何在 Android 中使用 runOnUiThread?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11140285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:07:52  来源:igfitidea点击:

How do we use runOnUiThread in Android?

androidui-thread

提问by user1049280

I'm new to Android and I'm trying to use the UI-Thread, so I've written a simple test activity. But I think I've misunderstood something, because on clicking the button - the app does not respond anymore

我是 Android 新手,我正在尝试使用 UI-Thread,所以我编写了一个简单的测试活动。但我想我误解了一些东西,因为点击按钮 - 应用程序不再响应

public class TestActivity extends Activity {

    Button btn;
    int i = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button)findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                runThread();
            }
        });
    }

    private void runThread(){
        runOnUiThread (new Thread(new Runnable() {  
            public void run() {
                while(i++ < 1000){
                    btn.setText("#"+i);
                    try {
                        Thread.sleep(300);
                    } 
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
             }
        }));
    }
}

回答by Vipul Shah

Below is corrected Snippet of runThreadFunction.

下面是更正的runThread函数片段。

private void runThread() {

    new Thread() {
        public void run() {
            while (i++ < 1000) {
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            btn.setText("#" + i);
                        }
                    });
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}

回答by user1049280

Just wrap it as a function, then call this function from your background thread.

只需将其包装为一个函数,然后从您的后台线程调用此函数。

public void debugMsg(String msg) {
    final String str = msg;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mInfo.setText(str);
        }
    });
}

回答by Graham Borland

You have it back-to-front. Your button click results in a call to runOnUiThread(), but this isn't needed, since the click handler is already running on the UI thread. Then, your code in runOnUiThread()is launching a new background thread, where you try to do UI operations, which then fail.

你把它从后到前。您的按钮单击会导致调用runOnUiThread(),但这不是必需的,因为单击处理程序已经在 UI 线程上运行。然后,您的代码runOnUiThread()将启动一个新的后台线程,您尝试在其中执行 UI 操作,但操作失败。

Instead, just launch the background thread directly from your click handler. Then, wrap the calls to btn.setText()inside a call to runOnUiThread().

相反,只需直接从您的点击处理程序启动后台线程。然后,将 tobtn.setText()的调用包装在 to的调用中runOnUiThread()

回答by Terranology

runOnUiThread(new Runnable() {
                public void run() {
                //Do something on UiThread
            }
        });

回答by Bajrang Hudda

There are several techniques using of runOnUiThread(), lets see all

有几种使用 runOnUiThread() 的技术,让我们看看所有

This is my main thread (UI thread) called AndroidBasicThreadActivityand I'm going to update it from a worker thread in various ways -

这是我的主线程(UI 线程),称为AndroidBasicThreadActivity,我将通过各种方式从工作线程更新它 -

public class AndroidBasicThreadActivity extends AppCompatActivity
{
    public static TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_android_basic_thread);

        textView = (TextView) findViewById(R.id.textview);

        MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this);
        Thread t1 = new Thread(myTask, "Bajrang");
        t1.start();
    }
}

1.) By passing Activity's instance as an argument on worker thread

1.) 通过将 Activity 的实例作为参数传递给工作线程

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {

        //perform heavy task here and finally update the UI with result this way - 
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
            }
        });
    }
}

2.) By using View's post(Runnable runnable) method in worker thread

2.) 通过在工作线程中使用 View 的 post(Runnable runnable) 方法

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {
     //perform heavy task here and finally update the UI with result this way - 
       AndroidBasicThreadActivity.textView.post(new Runnable()
      { 
        @Override
        public void run()
        {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });

    }
}

3.) By using Handler class from android.os packageIf we don't have the context (this/ getApplicationContext()) or Activity's instance (AndroidBasicThreadActivity.this) then we have to use Handler class as below -

3.) 通过使用 android.os 包中的 Handler 类如果我们没有上下文 (this/getApplicationContext()) 或 Activity 的实例 (AndroidBasicThreadActivity.this) 那么我们必须使用 Handler 类,如下所示 -

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
   public void run()
  {
  //perform heavy task here and finally update the UI with result this way - 
  new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });
  }
}

回答by Shivam Yadav

If using in fragment then simply write

如果在片段中使用,那么只需写

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // Do something on UiThread
    }
});

回答by Varun Chandran

We use Worker Thread to make Apps smoother and avoid ANR's. We may need to update UI after the heavy process in worker Tread. The UI can only be updated from UI Thread. In such cases, we use Handler or runOnUiThread both have a Runnable run method that executes in UI Thread. The onClick method runs in UI thread so don't need to use runOnUiThread here.

我们使用 Worker Thread 使应用程序更流畅并避免 ANR。在工作人员 Tread 的繁重过程之后,我们可能需要更新 UI。UI 只能从 UI 线程更新。在这种情况下,我们使用 Handler 或 runOnUiThread 都有一个在 UI 线程中执行的 Runnable run 方法。onClick 方法在 UI 线程中运行,因此这里不需要使用 runOnUiThread。

Using Kotlin

使用 Kotlin

While in Activity,

在活动期间,

this.runOnUiThread {
      // Do stuff
}

From Fragment,

从片段,

activity?.runOnUiThread {
      // Do stuff
}

Using Java,

使用 Java

this.runOnUiThread(new Runnable() {
     void run() {
         // Do stuff
     }
});

回答by MrG

thy this:

你这个:

@UiThread
    public void logMsg(final String msg) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Log.d("UI thread", "I am the UI thread");


            }
        });
    }

回答by Keshav Gera

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gifImageView = (GifImageView) findViewById(R.id.GifImageView);
        gifImageView.setGifImageResource(R.drawable.success1);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //dummy delay for 2 second
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //update ui on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        gifImageView.setGifImageResource(R.drawable.success);
                    }
                });

            }
        }).start();

    }

回答by Keshav Gera

You can use from this sample :

您可以从此示例中使用:

In the following example, we are going to use this facility to publish the result from a synonym search that was processed by a background thread.

在以下示例中,我们将使用此工具发布由后台线程处理的同义词搜索的结果。

To accomplish the goal during the OnCreate activity callback, we will set up onClickListener to run searchTask on a created thread.

为了在 OnCreate 活动回调期间完成目标,我们将设置 onClickListener 以在创建的线程上运行 searchTask。

When the user clicks on the Search button, we will create a Runnable anonymous class that searches for the word typed in R.id.wordEt EditText and starts the thread to execute Runnable.

当用户点击 Search 按钮时,我们将创建一个 Runnable 匿名类,该类搜索 R.id.wordEt EditText 中键入的单词并启动线程执行 Runnable。

When the search completes, we will create an instance of Runnable SetSynonymResult to publish the result back on the synonym TextView over the UI thread.

搜索完成后,我们将创建 Runnable SetSynonymResult 的实例,以通过 UI 线程将结果发布回同义词 TextView 上。

This technique is sometime not the most convenient one, especially when we don't have access to an Activity instance; therefore, in the following chapters, we are going to discuss simpler and cleaner techniques to update the UI from a background computing task.

这种技术有时不是最方便的,尤其是当我们无法访问 Activity 实例时;因此,在接下来的章节中,我们将讨论从后台计算任务更新 UI 的更简单、更清晰的技术。

public class MainActivity extends AppCompatActivity {

    class SetSynonymResult implements Runnable {
        String synonym;

        SetSynonymResult(String synonym) {
            this.synonym = synonym;
        }

        public void run() {
            Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d",
                    synonym, Thread.currentThread().getId()) + " !");
            TextView tv = (TextView) findViewById(R.id.synonymTv);
            tv.setText(this.synonym);
        }
    }

    ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button search = (Button) findViewById(R.id.searchBut);
        final EditText word = (EditText) findViewById(R.id.wordEt);
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Runnable searchTask = new Runnable() {
                    @Override
                    public void run() {
                        String result = searchSynomim(word.getText().toString());
                        Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s",
                                word.getText(), Thread.currentThread().getName()));
                        runOnUiThread(new SetSynonymResult(result));
                    }
                };
                Thread thread = new Thread(searchTask);
                thread.start();
            }
        });

    }

    static int i = 0;

    String searchSynomim(String word) {
        return ++i % 2 == 0 ? "fake" : "mock";
    }
}

Source:

来源

asynchronous android programming Helder Vasconcelos

异步android编程Helder Vasconcelos