从其他线程访问视图(Android)

时间:2011-11-18 13:25:42

标签: java android multithreading

我正在开发一个Android应用程序,我有一个启动/暂停某些模拟过程的按钮。在此过程运行时,我需要实时输出一些数据。但是当我为模拟创建一个新线程时,我无法从该线程访问视图(让它成为TextView),因为它们只能从创建它们的线程访问。另一方面,新线程是必要的,因为否则用户在模拟运行时将无法执行任何操作(例如,按某些其他按钮)。在这种情况下,创建新服务还需要创建新线程。我该如何解决这个问题?

5 个答案:

答案 0 :(得分:6)

你可以通过多种方式处理它,

  1. 尝试在此使用 AsyncTask ,您的后台工作在doInBackGround()方法中完成,您的UI不会阻止,您也可以访问这些视图您通过 publishProgress()和onProgressUpdate()在其上下文中调用AsyncTask的Activity的活动。

  2. 如果您使用简单线程,然后使用处理程序或消息或runOnUiThread ,则可以更新主线程视图。

  3. 但是,in your way I think AsyncTask is best for you.

答案 1 :(得分:3)

您可以使用android.os.Handler解决问题。 Handler实例绑定到创建它的线程,您可以将Runnables发布到它,它将在绑定的线程中执行它们。例如:

import android.os.Handler;
import android.widget.TextView;

public class MyActivity extends Activity {
  private Handler uiHandler;
  private TextView simulationStatus;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    ...
    uiHandler = new Handler();
    ...
    simulationStatus = (TextView) findViewById(R.id.simulationStatus);
    ...
  }

  // This method is to be executed on the simulation thread.
  public void simulate() {
    ...
    final String simulationStatusText = ...;
    ...
    uiHandler.post(new Runnable() {
      @Override
      public void run() {
        // This is run on the UI thread.
        simulationStatus.setText(simulationStatusText);
        ...
      }
    });
  }

  ...
}

您也可以使用AsyncTask。例如,请参阅链接。

答案 2 :(得分:2)

可以访问它们,但只能是只读的。你的意思是你想从视图上的一个线程触发更改。从工作线程(非UI)无法触发这些更改,您需要使用.runOnUiThread()或使用Handlers。在想要显示内容的位置使用这些内容,例如在.runOnUiThread()中更新textview,

示例:

myThread = new Thread()
        {

            @Override
            public void run() {
                //yourOperation
                MyActivity.this.runOnUiThread(new Runnable(){

                    @Override
                    public void run() {
                        if(e!=null)
                        {
                            myTextView.setText("something");
                        }

                    }});
                super.run();
            }
        };
        myThread.start();

答案 3 :(得分:1)

将活动传递给您的主题,并从内部使用它来访问您的观点。

// from your activity:
myExternalThread = new MyCustomCode(this); // <-- activity passed

// your "simulation process" constructor:
public MyCustomCode(Activity parent) {
    this.parent = parent;
}

// and when you want to access views:
parent.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        parent.findViewById(R.id.text_view);
        ... do something to your UI ...
    }
});

创建这些外部任务的首选方法是使用AsyncTask(然后您不必担心runOnUiThread,以及其他好处)。我不知道它是否适用于您的情况,但您应该检查一下。

答案 4 :(得分:1)

你必须将你想要显示的数据存储到public var中,让你的Thread通过Handler.post调用Runnable(runnable) Runnable的run()方法中的代码能够访问Textview