我们如何在Android中使用runOnUiThread?
我是Android新手,我正在尝试使用UI线程,所以我编写了一个简单的测试活动。但我想我误解了什么,因为点击按钮,应用程序不再响应我们如何在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
公共类测试活动扩展活动{
按钮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