Как использовать многопоточность в Android для функции обработки событий (SensorListeners) - PullRequest
1 голос
/ 07 марта 2011

В моем коде Android есть механизм обработки событий, позволяющий записывать значения датчиков в файл. Прямо сейчас я делаю это в основном потоке пользовательского интерфейса, и, следовательно, отзывчивость кнопок пользовательского интерфейса очень вялая, и я хотел бы ускорить это.

Как я могу использовать многопоточность в функциях обработки событий? Я пытаюсь сделать это так:

  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, он записывает в файл и затем устанавливает для WriteNow значение false. Тем не менее, я понимаю, что это неправильный подход, потому что поток будет выполняться один раз, а затем прекратит выполнение. Когда я попробовал простой пример с помощью while (true) и wait (), я обнаружил, что поток прерывается миллионы раз.

Итак, как мне заключить этот механизм обработки событий в один поток для ускорения процесса?

Спасибо!

Ответы [ 2 ]

1 голос
/ 07 марта 2011

Вы можете попробовать один из следующих подходов:

  1. Похоже, вы пытаетесь постоянно поддерживать поток писателя; то, что вы можете сделать, это создать поток только тогда, когда вам это нужно. Взгляните на пример в документации 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
            [ . . . ]
        }
    }
    

    Поскольку не похоже, что вы что-то делаете в потоке пользовательского интерфейса после того, как закончите писать, вам не нужно беспокоиться о 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() для общего объекта, когда есть данные, доступные для записи, и поток записи будет пробужден. Записывающий поток должен затем написать и повторно открыть. Взгляните на этот урок .

    Что касается прерывания вашего потока, ваш поток может быть прерван по ряду причин, поэтому это хорошая практика (особенно при использовании wait()), чтобы убедиться, что условие, которое вы проверяли перед Вы позвонили по номеру wait(), все еще действительны, потому что могли быть разбужены либо из-за вызова notify()/notifyAll(), либо из-за прерывания.

0 голосов
/ 07 марта 2011
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....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...