【问题标题】:Update the UI outside the main thread更新主线程外的 UI
【发布时间】:2013-05-05 05:01:04
【问题描述】:

我对 android 完全陌生,只是想知道在主线程之外更新 UI 是否可行且可行。仅从我在下面列出的代码中,我就知道从这段代码中;这是不可能的。但是,我只想使用另一个线程更新 UI。请帮助我提前谢谢!

 package com.example.app;

 import java.util.Random;
  import android.os.Bundle;
  import android.app.Activity;
  import android.view.Menu;
 import android.view.View;
  import android.widget.Button;
 import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {
private Button b;
public ImageView I1;
 public ImageView I2;
 public ImageView I3;
public ImageView I4;
public TextView T;
public TextView s;
@Override

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

 I1=new ImageView(this);
 I1=(ImageView) findViewById(R.id.imag1);
 I1.setVisibility(View.INVISIBLE);

 I2=new ImageView(this);
 I2=(ImageView) findViewById(R.id.imag2);
 I2.setVisibility(View.INVISIBLE);

 I3=new ImageView(this);
 I3=(ImageView) findViewById(R.id.imag3);
 I3.setVisibility(View.INVISIBLE);

 I4=new ImageView(this);
 I4=(ImageView) findViewById(R.id.imag4);
 I4.setVisibility(View.INVISIBLE);

 T=(TextView)findViewById(R.id.time);
 s=(TextView)findViewById(R.id.score);

Thread t=new Thread(new MyThread());
t.start();
  }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

private class MyThread implements Runnable{
Random randomGenerator = new Random();
int n;
public void run(){

    while(true){
        n=randomGenerator.nextInt(8);

        if(n==1){
            I1.setVisibility(View.VISIBLE);

        }
        if(n==2){
            I2.setVisibility(View.VISIBLE);
        }

        if(n==3){
            I3.setVisibility(View.VISIBLE);
        }

        if(n==4){
            I4.setVisibility(View.VISIBLE);
        }
        try {
            Thread.currentThread().sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
             e.getStackTrace();
        }
    }

   }




   }
   }

【问题讨论】:

  • 您应该阅读更多关于 android 和多线程的信息,您的代码存在设计缺陷。 UI 不应由主线程的任何其他线程更新,如果您费心阅读文档,您会知道这一点。但是,android 为您提供了一些工具,让您能够从其他线程发送的 oders 中更新 UI,但您必须阅读文档才能了解如何操作。
  • 您能否给我有关该特定文档的链接?
  • 这里,首先是:Processes and Thread

标签: java android multithreading user-interface


【解决方案1】:

使用activity.runOnUiThread

Acivity.runOnUiThread(new Runnable() {
    public void run() {
        //something here
    }
});

【讨论】:

    【解决方案2】:

    您不能直接从非 UI 线程更新 UI,但您可以使用 Handler 对象或 AsyncTask 对象与 UI 线程进行通信。 AsyncTask 最方便的使用方式:

    1. AsyncTask的.doInBackground()方法在非ui线程中运行
    2. .onProgressUpdate() 在 UI 线程中运行,因此可以更改视图
    3. 您可以使用 doInBackground() 中的 publishProgress() 方法将数据传递给 .onProgressUpdate。

    抱歉,如果方法名称有错误。 阅读http://developer.android.com/guide/components/processes-and-threads.html了解详情。

    【讨论】:

      【解决方案3】:

      工作线程永远不能更新主线程,因为只有主线程可以渲染 UI 元素(TextView、EditText 等),如果我们尝试更新肯定会出现异常。

      myAcitity.runOnUiThread(new Runnable() {
          public void run() {
              //here you can update your UI elements because this code is going to executed by main thread
          }
      });
      

      否则可以使用 View 类的 post 方法

      myView.post(new Runnable() {
              public void run() {
                  //here you can update your UI elements because this code is going to executed by main thread
              }
          });
      

      【讨论】:

        【解决方案4】:

        您必须使用 Handler 实例并使用 post 方法在 UI 线程的队列中添加一个 Runnable。如果你在一个 Activity 中,你可以使用 runOnUiThread 这是一个“快捷方式”来做同样的事情

        【讨论】:

          【解决方案5】:

          只有主线程可以更新 UI。如果您的线程想要更​​新 UI,请使用 activity.runOnUiThread()

          但是,您的操作只是排队等待在 UI 线程中运行(如果您不是从 UI 线程运行它),这意味着它可以稍后更新 UI。

          http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

          【讨论】:

          • 但是我可以使用 sleep 方法来暂停执行吗?我的意思是如果在 RunOnUIThread() 中使用 sleep ,主线程将被暂停,这将产生问题!
          • 这是使用 UI 的主要原则之一。在最短的时间内阻塞 UI 线程,在后台线程中执行您的逻辑,并使用相关准备好的数据安排 UI 更新。
          猜你喜欢
          • 2017-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-14
          • 2013-04-09
          • 1970-01-01
          相关资源
          最近更新 更多