如何在 Android 中使用 runOnUiThread?

我是 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();
}
}
}
}));
}
}
412773 次浏览

你把它反过来放在前面。您的按钮单击会导致对 runOnUiThread()的调用,但是这并不需要,因为单击处理程序已经在 UI 线程上运行了。然后,runOnUiThread()中的代码启动一个新的后台线程,在这里尝试执行 UI 操作,但是失败了。

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

下面是 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();
}

只要把它包装成一个函数,然后从后台线程调用这个函数。

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

您可以从这个示例中使用:

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

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

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

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

这种技术有时并不是最方便的,尤其是当我们不这样做的时候 可以访问 Activity 实例; 因此,在下面的章节中,我们 将讨论更简单和更清晰的技术从背景更新用户界面 计算任务。

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

来源 :

异步机器人编程 Helder Vasconcelos

我是这样使用它的:

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

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

这是我的主线程(UI 线程)称为 线程活动,我将从一个工作线程以各种方式更新它-

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();
}
}

通过在工作线程上将 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)在工作线程中使用 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)使用来自 android.os 包的 Handler 类 如果我们没有上下文(this/getApplicationContext())或活动的实例(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.");
}
});
}
}

你的这个:

@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");




}
});
}
  @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();


}

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

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

试试这个: getActivity().runOnUiThread(new Runnable...

因为:

1)在您对 RunOnUiThread的调用中隐含的这一点指的是 AsyncTask,而不是您的片段。

2)片段没有 runOnUiThread。

然而,活动可以。

注意,如果您已经在主线程上,Activity 只是执行 Runnable,否则它将使用一个 Handler。你可以在你的片段中实现一个处理程序,如果你不想担心它的上下文,它实际上非常简单:

//类实例

private Handler mHandler = new Handler(Looper.getMainLooper());

//代码中的任何其他地方

mHandler.post(<your runnable>);

//^ 这将始终在主线程上的下一个运行循环中运行。

我们使用工作线程,使应用程序更加顺畅,避免 ANR 的。我们可能需要更新用户界面后,沉重的过程中工人履带。 UI 只能从 UI 线程更新。在这种情况下,我们使用 Handler 或 runOnUiThread 都有一个在 UIThread 中执行的 Runnable run 方法。 OnClick 方法在 UI 线程中运行,因此这里不需要使用 runOnUiThread。

利用科特林

活动期间,

this.runOnUiThread {
// Do stuff
}

从碎片,

activity?.runOnUiThread {
// Do stuff
}

使用 Java ,

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

对于 fragment使用:

requireActivity().runOnUiThread(() -> {
//your code logic
});

对于 activity使用:

runOnUiThread(() -> {
//your code logic
});

RunOnUiThread 用于用我们的后台线程更新 UI。想了解更多信息,请访问: http://www.tutorialspoint.com/how-do-we-use-runonuithread-in-android”rel = “ nofollow norefrer”> https://www.tutorialspoint.com/how-do-we-use-runonuithread-in-android