java - 自动更新 UI

标签 java multithreading android

我正在开发一个 Android 程序,该程序从一个单独的类获取传感器数据(我在 onSensorChange 方法中打印出来的数据,看起来不错)。不,我想用我获得的数据更新我的用户界面。 UI 由 Activity (主 Activity )中的一些 TextView 组成,在 onCreate 方法中我初始化获取传感器数据的传感器类。

我尝试在 Activity 的 onCreate 方法中使用线程 UIthread,但 TextView 没有更新。有人有建议吗?

onCreate 看起来像这样(在 onSensorChange 的打印中我得到了正确的数据):

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


CompassHeading = (TextView) findViewById(R.id.CompassValue);
AccelValueZ = (TextView) findViewById(R.id.AccelValueZ);
AccelValueY = (TextView) findViewById(R.id.AccelValueY);
AccelValueX = (TextView) findViewById(R.id.AccelValueX);
GyroValue = (TextView) findViewById(R.id.GyroValue);

SensorM = new SensorModule(getApplicationContext()); //<<---Created instance of SensorModule

new Thread(new Runnable(){
    //@Override
        public void run(){

            CompassHeading.setText("Heading: " + Float.toString(SensorM.AccelerationResult[0]) + " degrees");

            AccelValueZ.setText(Float.toString(Math.round(SensorM.AccelerationResult[2])));
            AccelValueY.setText(Float.toString(Math.round(SensorM.AccelerationResult[1])));
            AccelValueX.setText(Float.toString(Math.round(SensorM.AccelerationResult[0]))); 

            GyroValue.setText("Orientation X (Roll) :"+ Float.toString(Math.round(SensorM.AccelerationData[2])) +"\n"+  
                              "Orientation Y (Pitch) :"+ Float.toString(Math.round(SensorM.AccelerationData[1])) +"\n"+  
                              "Orientation Z (Yaw) :"+ Float.toString(Math.round(SensorM.AccelerationData[0])));                
        }
    });

以及SensorModule类的onSensorChange:

public void onSensorChanged(SensorEvent event) {
System.out.println("In onSensorChanged");

System.out.println("=====================");
// Get a local copy of the sensor values
System.arraycopy(event.values, 0, AccelerationData, 0, event.values.length);    

AccelerationData[0] = AccelerationData[0] / SensorManager.GRAVITY_EARTH;
AccelerationData[1] = AccelerationData[1] / SensorManager.GRAVITY_EARTH;
AccelerationData[2] = AccelerationData[2] / SensorManager.GRAVITY_EARTH;

// Get result
AccelerationResult = GetAcceleration(AccelerationData); 

    System.out.println("Orientation X (Roll) :"+ Float.toString(Math.round(AccelerationData[2])) +"\n"+  
                   "Orientation Y (Pitch) :"+ Float.toString(Math.round(AccelerationData[1])) +"\n"+  
                   "Orientation Z (Yaw) :"+ Float.toString(Math.round(AccelerationData[0])));

    System.out.println("Acceleration X :"+ Float.toString(Math.round(AccelerationResult[2])) +"\n"+  
                   "Acceleration Y :"+ Float.toString(Math.round(AccelerationResult[1])) +"\n"+  
                   "Acceleration Z :"+ Float.toString(Math.round(AccelerationResult[0])));
}

更新

谢谢大家的建议!我修改了主要 Activity 代码。这里我创建了一个线程、可运行对象和一个处理程序。现在我得到了这样的数据,但问题是我有时只得到新数据,而不是所有字段都更新。我是否正确实现了线程和处理程序?我想尽快获得当前字段的所有数据的更新。有人看到下面的代码有问题吗?欢迎提出所有建议!

以下是主要 Activity 代码:

    package com.example.sensormodule;

import com.example.SensorModuleClass.SensorModule;
import com.example.sensormodule.R;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class MainActivity extends Activity{

    TextView CompassHeading;
    TextView AccelValueZ;
    TextView AccelValueY;
    TextView AccelValueX;
    TextView GyroValue;
    String value;   

    SensorModule SensorM;

    // Need handler for callbacks to the UI thread
    final Handler UpdateUIHandler = new Handler();

    // Create runnable for posting
    final Runnable UpdateResults = new Runnable() {
        public void run() {
            UpdateResultToUI();
        }
    };

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


        CompassHeading = (TextView) findViewById(R.id.CompassValue);
        AccelValueZ = (TextView) findViewById(R.id.AccelValueZ);
        AccelValueY = (TextView) findViewById(R.id.AccelValueY);
        AccelValueX = (TextView) findViewById(R.id.AccelValueX);
        GyroValue = (TextView) findViewById(R.id.GyroValue);

        SensorM = new SensorModule(getApplicationContext());

            StartUpdateToUI();
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    protected void StartUpdateToUI() {

        // Fire off a thread to do some work that we shouldn't do directly in the UI thread
        Thread t = new Thread() {
            public void run() {

                while(true){
                //Keep updating the UI
                    UpdateUIHandler.post(UpdateResults);
                }
            }
        };
            t.start();
    }


    private void UpdateResultToUI() {

        CompassHeading.setText("Heading: " + Float.toString(SensorM.AccelerationResult[0]) + " degrees");

        AccelValueZ.setText(Float.toString(Math.round(SensorM.AccelerationResult[2])));
        AccelValueY.setText(Float.toString(Math.round(SensorM.AccelerationResult[1])));
        AccelValueX.setText(Float.toString(Math.round(SensorM.AccelerationResult[0]))); 

        GyroValue.setText("Orientation X (Roll) :"+ Float.toString(Math.round(SensorM.AccelerationData[2])) +"\n"+  
                          "Orientation Y (Pitch) :"+ Float.toString(Math.round(SensorM.AccelerationData[1])) +"\n"+  
                          "Orientation Z (Yaw) :"+ Float.toString(Math.round(SensorM.AccelerationData[0])));   
    }
}

最佳答案

我在这里看到几个问题:

1) 您正在创建一个新的Thread,但您没有调用它的start(),因此Thread 永远不会运行。

2) 如果您确实调用了 start(),您将收到一个 Exception,说明您正在尝试从某个线程修改 UI Thread。背景线程

如果您需要在某个后台 Thread 完成后更新 UI,您应该使用 AsyncTaskHandler

关于java - 自动更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20051596/

相关文章:

java - (几乎)相同的代码在一个地方产生未经检查的分配,而在另一个地方则不会

c# - 我们如何为 C# 接口(interface)使用内部匿名?

c# - 为什么显式管理线程是一件坏事?

android - 如果我想让我的应用程序在所有 Android 设备上运行,是否有必要创建 "small, normal, large and xlarge android xml layouts"文件夹

android - 在 Android 中创建自定义硬件传感器

java - Spring Aop 依赖关系

java - 如何使用apache commons解析xml中的配置文件?

c# - 建议数据结构/同步方法

c++ - 异步过程调用被另一个线程中断?

android - 从 Android 摄像头到 Wowza 服务器的视频流。 (RTMP)