如何在 Android 中使用多线程来实现事件处理函数 (SensorListeners)
我的 Android 代码中有一个事件处理机制,可以将传感器值转储到文件中。现在,我正在主 UI 线程中执行此操作,因此 UI 按钮响应速度非常缓慢,我想加快速度。
如何在事件处理函数上使用多线程?我试图这样做:
- 创建一个全局变量 writeNow。
- 当传感器值发生变化时,设置 WriteNow = true
在类中创建一个线程,如下所示:
线程 thread1 = new Thread() { 公共无效运行() { if(writeNow == true) { 尝试 { fos.write(s.getBytes()); } 捕获(IOException e) { e.printStackTrace(); } 现在写=假; } } };
因此,每当 writeNow 为 true 时,它将写入文件,然后将 WriteNow 设置为 false。但是,我意识到这不是正确的方法,因为线程将执行一次然后停止执行。当我尝试使用 while(true) 和 wait() 的简单示例时,我发现线程被中断了数百万次。
那么如何将此事件处理机制封装在单个线程中以加速进程呢?
谢谢!
I have an event handling mechanism in my Android code to dump the sensor values in a file. Right now, I'm doing it in the main UI thread and hence the UI button responsiveness is very sluggish and I would like to speed it up.
How can I use multithreading on event handling functions? I'm trying to do it like this:
- Create a global variable writeNow.
- When the sensor value changes, set WriteNow = true
Create a thread in the class which looks like this:
Thread thread1 = new Thread() { public void run() { if(writeNow == true) { try { fos.write(s.getBytes()); } catch (IOException e) { e.printStackTrace(); } writeNow = false; } } };
Thus, whenever writeNow is true, it will write to a File and then set WriteNow to false. However, I realize this is not the right approach, because the thread will execute once and then stop executing. When I tried a simple example with a while(true) and wait(), I found that the thread is interrupted millions of times.
So how do I enclose this event handling mechanism in a single thread, for speeding up a process?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试以下方法之一:
看起来您正在尝试让编写器线程始终运行;你能做的就是仅在需要时才生成线程。查看 Android 文档中的示例,了解 处理 UI 中昂贵的操作线程。
以下是该页面的示例:
由于在完成编写后,您看起来并没有在 UI 线程中执行任何操作,因此您实际上不需要为
Handler
操心。但是您可能希望在文件写入后使用它来显示Toast
。另一方面,如果您仍然想让线程运行,您可以使用
sleep()
并定期唤醒并检查writeNow
的状态。请注意,这很快就会变得复杂,如果您的线程在新数据进入时处于休眠状态,并且当它醒来时,甚至已接收到较新的数据并覆盖了先前的字节,您可能会丢失想要写入的字节。您需要某种队列来管理它。
我不确定你用
wait()
做了什么,但这应该也有效,而且事实上,这是解决涉及消费者和生产者问题的方法。这个想法是让你的线程在共享对象(比如你的字节队列)上同步和 wait() ;当有数据可供写入时,第二个线程将在共享对象上调用notify()
,并且写入器线程将被唤醒。然后编写器线程应该写入并重新循环。请查看本教程。至于线程的中断,您的线程可能会因多种原因而被中断,这就是为什么确保您检查的条件是好的做法(特别是在使用
wait()
时) 在你调用wait()
之前仍然有效,因为你可能因为调用notify()/notifyAll()
而被唤醒或者因为中断。You can try one of the following approaches:
It looks like you're trying to keep your writer thread running all the time; what you can do is spawn the thread only when you need it. Take a look at the example in the Android documentation for handling expensive operation in the UI thread.
Here is the example from that page:
Since it doesn't look like you're doing anything in the UI thread once you finish writing you don't really need to bother with a
Handler
. But you might want to use it to display aToast
once the file has been written to.On the other hand, if you still want to have a thread running, you might have it
sleep()
and periodically wake up and check the status ofwriteNow
.Note that this will quickly get complicated and you might lose the bytes you want to write if your thread is sleeping when new data comes in and when it wakes up, even newer data has been received and has overwritten the previous bytes. You'd need some sort of a queue to manage that.
I'm not sure what you were doing with the
wait()
but that should've also worked and is in fact, the approach for problems involving a consumer and producer. The idea is to have your thread synchronize andwait()
on a shared object (like perhaps your queue of bytes); a second thread will callnotify()
on the shared object when there is data available to write and the writer thread will be woken up. The writer thread should then write and reloop. Take a look at this tutorial.As for the interruption of your thread, your thread may be interrupted for a number of reasons which is why it is good practice (especially when using
wait()
) to ensure that the condition you checked before you calledwait()
is still valid because you could've been woken because of either a call tonotify()/notifyAll()
or because of an interruption.