如何在 Android 中使用多线程来实现事件处理函数 (SensorListeners)

发布于 2024-10-20 08:45:56 字数 741 浏览 1 评论 0原文

我的 Android 代码中有一个事件处理机制,可以将传感器值转储到文件中。现在,我正在主 UI 线程中执行此操作,因此 UI 按钮响应速度非常缓慢,我想加快速度。

如何在事件处理函数上使用多线程?我试图这样做:

  1. 创建一个全局变量 writeNow。
  2. 当传感器值发生变化时,设置 WriteNow = true
  3. 在类中创建一个线程,如下所示:

    线程 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:

  1. Create a global variable writeNow.
  2. When the sensor value changes, set WriteNow = true
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

衣神在巴黎 2024-10-27 08:45:56

您可以尝试以下方法之一:

  1. 看起来您正在尝试让编写器线程始终运行;你能做的就是仅在需要时才生成线程。查看 Android 文档中的示例,了解 处理 UI 中昂贵的操作线程

    以下是该页面的示例:

    public class MyActivity 扩展 Activity {
    
        [。 。 。 ]
        // 需要回调 UI 线程的处理程序
        最终处理程序 mHandler = new Handler();
    
        // 创建用于发布的可运行程序
        最终 Runnable mUpdateResults = new Runnable() {
            公共无效运行(){
                updateResultsInUi();
            }
        };
    
        @覆盖
        protected void onCreate(Bundle savingInstanceState) {
            super.onCreate(savedInstanceState);
    
            [。 。 。 ]
        }
    
        受保护的无效startLongRunningOperation(){
    
            // 关闭一个线程来完成一些我们不应该直接在 UI 线程中完成的工作
            线程 t = 新线程() {
                公共无效运行(){
                    mResults = doSomethingExpense();
                    mHandler.post(mUpdateResults);
                }
            };
            t.start();
        }
    
        私有无效 updateResultsInUi() {
    
            // 回到 UI 线程——根据 mResults 中的数据更新我们的 UI 元素
            [。 。 。 ]
        }
    }
    

    由于在完成编写后,您看起来并没有在 UI 线程中执行任何操作,因此您实际上不需要为 Handler 操心。但是您可能希望在文件写入后使用它来显示 Toast

  2. 另一方面,如果您仍然想让线程运行,您可以使用 sleep() 并定期唤醒并检查 writeNow 的状态。

    线程 thread1 = new Thread()  
    {  
        公共无效运行()  
        {  
            而(真)
            {
                if(writeNow == true)  
                {  
                    尝试 
                    {  
                        fos.write(s.getBytes());  
                    } 
                    捕获(IOException e) 
                    {  
                         e.printStackTrace();  
                    }  
    
                    现在写=假;  
                }
    
                尝试
                {
                    线程睡眠(100); //休眠100毫秒
                }
                捕获(InterruptedException e) 
                {  
                     Log.d('', e.getMessage());  
                }  
            }
        }  
     }; 
    

    请注意,这很快就会变得复杂,如果您的线程在新数据进入时处于休眠状态,并且当它醒来时,甚至已接收到较新的数据并覆盖了先前的字节,您可能会丢失想要写入的字节。您需要某种队列来管理它。

  3. 我不确定你用 wait() 做了什么,但这应该也有效,而且事实上,这是解决涉及消费者和生产者问题的方法。这个想法是让你的线程在共享对象(比如你的字节队列)上同步和 wait() ;当有数据可供写入时,第二个线程将在共享对象上调用 notify(),并且写入器线程将被唤醒。然后编写器线程应该写入并重新循环。请查看本教程

    至于线程的中断,您的线程可能会因多种原因而被中断,这就是为什么确保您检查的条件是好的做法(特别是在使用 wait() 时) 你调用wait()之前仍然有效,因为你可能因为调用notify()/notifyAll()而被唤醒或者因为中断。

You can try one of the following approaches:

  1. 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:

    public class MyActivity extends Activity {
    
        [ . . . ]
        // Need handler for callbacks to the UI thread
        final Handler mHandler = new Handler();
    
        // Create runnable for posting
        final Runnable mUpdateResults = new Runnable() {
            public void run() {
                updateResultsInUi();
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            [ . . . ]
        }
    
        protected void startLongRunningOperation() {
    
            // 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() {
                    mResults = doSomethingExpensive();
                    mHandler.post(mUpdateResults);
                }
            };
            t.start();
        }
    
        private void updateResultsInUi() {
    
            // Back in the UI thread -- update our UI elements based on the data in mResults
            [ . . . ]
        }
    }
    

    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 a Toast once the file has been written to.

  2. 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 of writeNow.

    Thread thread1 = new Thread()  
    {  
        public void run()  
        {  
            while(true)
            {
                if(writeNow == true)  
                {  
                    try 
                    {  
                        fos.write(s.getBytes());  
                    } 
                    catch (IOException e) 
                    {  
                         e.printStackTrace();  
                    }  
    
                    writeNow = false;  
                }
    
                try
                {
                    Thread.sleep(100); //sleep for 100 ms
                }
                catch (InterruptedException e) 
                {  
                     Log.d('', e.getMessage());  
                }  
            }
        }  
     }; 
    

    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.

  3. 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 and wait() on a shared object (like perhaps your queue of bytes); a second thread will call notify() 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 called wait() is still valid because you could've been woken because of either a call to notify()/notifyAll() or because of an interruption.

且行且努力 2024-10-27 08:45:56
Handler handler = null;

handler = new Handler();

//create another class for and make consrtuctor as u want. so that u can use that effectively.
//for example.                                                      

popupIndex = new IndexThread(handler,head, target,ltp,price,IndexNifty.this,columsView,call);           

popupIndex.setColumnViewexit(columsView);
handler.postDelayed(popupIndex, 300);


//another class
public IntraThread(Handler handler,String script,int target,int ltp,int price,Intraday intraday,TextView columsView,String call){
        super();
        this.target = target;
        this.ltp = ltp;
        this.price = price;     
        this.intraday = intraday;
        this.columsView = columsView;
        this.script= script;
        this.handler= handler;
        this.call= call;
}

public void run(){
// write ur code here....
}
Handler handler = null;

handler = new Handler();

//create another class for and make consrtuctor as u want. so that u can use that effectively.
//for example.                                                      

popupIndex = new IndexThread(handler,head, target,ltp,price,IndexNifty.this,columsView,call);           

popupIndex.setColumnViewexit(columsView);
handler.postDelayed(popupIndex, 300);


//another class
public IntraThread(Handler handler,String script,int target,int ltp,int price,Intraday intraday,TextView columsView,String call){
        super();
        this.target = target;
        this.ltp = ltp;
        this.price = price;     
        this.intraday = intraday;
        this.columsView = columsView;
        this.script= script;
        this.handler= handler;
        this.call= call;
}

public void run(){
// write ur code here....
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文