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 が true の場合は常に、File に書き込み、WriteNow を false に設定します。ただし、スレッドは一度実行されてから停止するため、これは正しいアプローチではないことに気付きました。while(true) と wait() を使用して簡単な例を試してみたところ、何百万回もスレッドが中断されていることがわかりました。

では、プロセスを高速化するために、このイベント処理メカニズムを単一のスレッドに含めるにはどうすればよいでしょうか?

ありがとう!

4

2 に答える 2

1

次のいずれかの方法を試すことができます。

  1. ライタースレッドを常に実行し続けようとしているようです。あなたができることは、あなたがそれを必要とするときだけスレッドをスポーンすることです。UIスレッドで高額な操作を処理するためのAndroidドキュメントの例を見てください。

    そのページの例を次に示します。

    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、ファイルが書き込まれた後の表示に使用することをお勧めします。

  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()書き込み可能なデータがあり、ライタースレッドがウェイクアップされると、2番目のスレッドが共有オブジェクトを呼び出します。その後、ライタースレッドは書き込みと再ループを行う必要があります。このチュートリアルをご覧ください。

    スレッドの中断に関しては、いくつかの理由でスレッドが中断される可能性があります。そのため、呼び出す前に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 に答える