1

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

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

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

    Thread thread1 = new Thread()  
    {  
      public void run()  
      {  
        if(writeNow == true)  
          {  
            try 
            {  
                fos.write(s.getBytes());  
            } 
            catch (IOException e) 
            {  
                 e.printStackTrace();  
            }  
            writeNow = false;  
          }  
      }  
     };  
    

因此,只要 writeNow 为真,它就会写入文件,然后将 WriteNow 设置为假。但是,我意识到这不是正确的方法,因为线程将执行一次然后停止执行。当我用while(true)和wait()尝试一个简单的例子时,我发现线程被中断了数百万次。

那么如何将这个事件处理机制封装在一个线程中,以加快进程呢?

谢谢!

4

2 回答 2

1

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

  1. 看起来你正试图让你的 writer 线程一直运行;您可以做的是仅在需要时才生成线程。查看 Android 文档中处理 UI 线程中昂贵操作的示例。

    这是该页面的示例:

    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
            [ . . . ]
        }
    }
    

    因为一旦你完成编写,你看起来并没有在 UI 线程中做任何事情,所以你真的不需要为Handler. 但是您可能希望Toast在文件写入后使用它来显示 a 。

  2. 另一方面,如果您仍然希望有一个线程运行,您可能会拥有它sleep()并定期唤醒并检查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());  
                }  
            }
        }  
     }; 
    

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

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

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

于 2011-03-07T05:46:41.383 回答
0
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....
}
于 2011-03-07T05:59:59.540 回答