-1

android 项目的目的是从硬件设备读取一些数据,然后在 UI 中更新它们。现在我们需要封装一些后台线程接收数据的代码,并提供一个函数让其他类从这个封装的类中获取数据。下面是我这个封装类的代码:

public class getDataFromUSB{
        private AtomicInteger usb_data = new AtomicInteger():
        private Random random;

        private Thread thread = new Thread(){
             @override
             public void run(){
                      while(!Thread.currentThread().isInterrupted()){
                          synchronized(usb_data){
                               usb_data.set(read_usb());
                               usb_notify();
                          }
                      }
        };

        public void start(){
             thread.start();
        }

        public int get_data(){
             int ret_data=0;
             synchronized(usb_data){
                     try{
                            usb_data.wait();
                     }catch(InterruptedException e){}
                     ret_data=usb_data.get();
             }
             return ret_data;
        }
        public int read_usb(){
             return random.nextInt();
        }
}

在主活动类中,我想不断地实时获取 USB 的数据,然后将其放在 UI 中的 textview 中。所以我这样称呼这个类:

final getDataFromUSB usb1=new getDataFromUSB();
usb1.start();
for(;;){
         myTextView.setText(String.valueof(usb1.get_data()));
}

但是 myTextView 中什么也没有出现。但是当我用

for(;;){
         Log.d(TAG,"data="+usb1.get_data());
}

我总是可以在我的日志中获得实时值。任何人都可以帮助解决这个问题吗?或者,如果您对封装这种功能有更好的想法并提供简单的函数,如 get_data() 可以提供实时数据,请告诉我。

4

2 回答 2

1

当您使用时,for(;;)您会创建一个无限循环,它永远不会暂停并尽可能快地运行。

所以其他线程并没有得到(很多)时间安排来实际做一些他们自己的处理。UI 线程(将重新绘制TextView)具有低优先级,因此无法TextView重新绘制 ..!

您可能需要多考虑一下:人眼的刷新率为每秒 30 帧。您的设备还具有最大刷新率,这比您更新TextView. 因此,通常以 60 fps 更新 UI。当然没有必要尽可能快地刷新 UI。(这对您的电池使用也更好!)

因此,您需要使用某种定时解决方案将刷新速度降低到 60 fps。

getDataFromUSB这也适用于线程的无限刷新率!以比您(将要)使用的速度更快的速度获取 USB 是没有意义的......

于 2013-01-22T16:23:29.830 回答
0

你读过关于 android 中的 UI 线程的任何内容吗?

您正在阻止运行循环的 UI 线程。所有 UI 绘图都发生在 UI 线程中。setText 只是设置属性。它不会更新视图。永远不要像以前那样阻塞 UI 线程。以处理程序为例。

于 2013-01-22T16:22:11.283 回答