Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.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
Java 从其他线程访问视图(Android)_Java_Android_Multithreading - Fatal编程技术网

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

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

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

你可以用。处理程序实例绑定到创建它的线程,您可以向它发布可运行文件,它将在绑定到的线程中执行这些文件。例如:

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

  ...
}

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

将活动传递给您的线程,并从内部使用它访问您的视图

// 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 ...
    }
});
//从您的活动中:

myExternalThread=新的MyCustomCode(此);// 你可以用很多方法来处理它

  • 尝试使用AsyncTask在这个方法中,您的后台工作是在doInBackGround()中完成的方法,您的UI将不会阻塞,您还可以通过publishProgress()和onProgressUpdate()访问活动视图,从中您可以通过上下文调用AsyncTask

  • 如果您使用的是简单线程,则使用处理程序或消息或runOnUiThread可以更新主线程的视图


  • 但是,以您的方式,我认为AsyncTask最适合您。

    您必须将想要显示的数据存储到公共var中,并让您的线程通过Handler.post(Runnable)调用Runnable
    Runnable的run()方法中的代码可以访问Textview,但只能以只读方式访问。您的意思是希望从视图上的线程触发更改。从工作线程(非UI)无法触发这些更改,您需要使用
    .runOnUiThread()
    或使用
    处理程序。在要显示某些内容时使用这些选项,例如在.runOnUiThread()中更新文本视图

    例如:

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

    你结帐了吗?它是一个实用类,可以帮助您轻松创建不同的线程并相应地更新UI元素。在这种情况下,您可以使用它的
    publishProgress()
    onProgressUpdate()
    方法。是否确实可以像您提到的那样仅从非ui线程读取视图?我对使用Bitmap drawingCache=view.getDrawingCache()从视图中读取位图很感兴趣,但我一直得到一个异常:CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图。