Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我们如何在Android中使用runOnUiThread?_Android_Ui Thread - Fatal编程技术网

我们如何在Android中使用runOnUiThread?

我们如何在Android中使用runOnUiThread?,android,ui-thread,Android,Ui Thread,我是Android新手,我正在尝试使用UI线程,所以我编写了一个简单的测试活动。但我想我误解了什么,因为点击按钮,应用程序不再响应 公共类测试活动扩展活动{ 按钮btn; int i=0; @凌驾 创建时的公共void(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(按钮)findViewById(R.id.btn); btn.setOnClic

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

公共类测试活动扩展活动{
按钮btn;
int i=0;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn=(按钮)findViewById(R.id.btn);
btn.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
runThread();
}
});
}
私有void runThread(){
runOnUiThread(新线程(新Runnable(){
公开募捐{
而(i++<1000){
btn.setText(“#”+i);
试一试{
睡眠(300);
} 
捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}));
}
}

您可以将它从后面放到前面。您的按钮单击会导致调用
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();
}
private void runThread(){
新线程(){
公开募捐{
而(i++<1000){
试一试{
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
btn.setText(“#”+i);
}
});
睡眠(300);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}.start();
}

只需将其包装为函数,然后从后台线程调用此函数

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

您可以从此示例中使用:

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

public void debugMsg(String msg) {
    final String str = msg;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mInfo.setText(str);
        }
    });
}
为了在OnCreate活动回调期间实现该目标,我们将设置 onClickListener在创建的线程上运行searchTask

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

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

这种技术有时不是最方便的,尤其是在我们不方便的时候 有权访问活动实例;因此,在接下来的章节中,我们将 下面将讨论从后台更新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";
    }
}
来源

我就是这样使用它的:

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

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

这是我的主线程(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.)将活动的实例作为辅助线程上的参数传递

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

    }
}
2.)在工作线程中使用视图的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 - 
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
            }
        });
    }
}
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包中的处理程序类 如果我们没有上下文(this/getApplicationContext())或活动的实例(AndroidBasicThreadActivity.this),那么我们必须使用如下处理程序类-

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


            }
        });
    }

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

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

尝试以下操作:
getActivity().runOnUiThread(新的可运行…

这是因为:

1) 调用runOnUiThread时隐含的含义是指AsyncTask,而不是您的片段

2) 片段没有runOnUiThread

然而,活动确实如此

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

//类实例

private Handler mHandler = new Handler(Looper.getMainLooper());
//代码中的任何其他地方

mHandler.post(<your runnable>);
mHandler.post();

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

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

使用Kotlin

在活动中,

this.runOnUiThread {
      // Do stuff
}
从碎片

activity?.runOnUiThread {
      // Do stuff
}
使用Java

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

这些垃圾不是马上就被收集了吗?可能您需要保留一些对线程的引用()@Nick:垃圾收集器也会监视堆栈,即当线程运行时,它不会被GC'ed.@Vipul,我有一个关于手机旋转的问题:我希望在我旋转手机后,该线程运行,并且不会创建新线程。您能否提供一些提示,说明如何防止在手机旋转后创建新线程?虽然单击处理程序确实已在UI线程中,但调用
runOnUiThread()
是不必要的,但应该是无害的。该方法的Javadoc表示“运行指定的acti