2011-03-07 4 views
1

Android 코드에 센서 값을 파일에 덤프하는 이벤트 처리 메커니즘이 있습니다. 지금 당장은 UI UI 스레드에서이를 수행하고 있으므로 UI ​​버튼의 응답 속도가 매우 느리고 속도를 높이고 싶습니다.Android에서 이벤트 핸들링 함수 (SensorListeners)에 MultiThreading을 사용하는 방법

이벤트 처리 기능에서 멀티 스레딩을 어떻게 사용할 수 있습니까? 나는 이것을 다음과 같이하려고 애 쓰고있다.

  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가 참일 때마다, 그것은 쓸 것 File을 누른 다음 WriteNow를 false로 설정합니다. 그러나 스레드가 한 번 실행 된 다음 실행이 중지되기 때문에 이것이 올바른 접근 방식이 아니라는 것을 알고 있습니다. while (true) 및 wait()를 사용하여 간단한 예제를 시도했을 때 스레드가 수백만 번 중단되었음을 발견했습니다.

그래서 프로세스 가속화를 위해이 이벤트 처리 메커니즘을 단일 스레드로 묶으십시오.

감사합니다.

답변

1

다음과 같은 방법 중 하나를 시도 할 수 있습니다 :

당신이 모든 시간을 실행하는 작가 스레드를 유지하기 위해 노력하고 마치
  1. ; 할 수있는 일은 필요할 때만 스레드를 생성하는 것입니다. Android 설명서의 handling expensive operation in the UI thread에 대한 예를 살펴보십시오. 당신이 정말 Handler 귀찮게 할 필요가 없습니다 작성을 완료 한 후에는 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 
         [ . . . ] 
        } 
    } 
    

    이 보이지 않는 : 여기

    해당 페이지의 예입니다 . 그러나 일단 파일이 작성되면 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()을 호출합니다. 그러면 작성자 스레드는 쓰기 및 다시 실행해야합니다. this tutorial을보십시오.스레드의 중단에 관해서는

    , 당신의 스레드가 좋습니다 wait()가 여전히 조건이 당신이 전화 전에 를 확인하도록 (특히 wait()를 사용하는) 이유 인 이유로 중단 될 수 있습니다 notify()/notifyAll()으로 전화했거나 중단으로 인해 깨울 수 있었기 때문에 유효합니다.

+0

이유는 100ms의 잠을해야합니까? 왜 항상 실행하는 동안 (사실) 유지하지? 실제로이 코드 조각을 시도했지만 UI 응답 성은 전혀 향상되지 않습니다 ... – Imelza

+0

스레드가 '잠자기'되지 않고 100 밀리 초일 필요는 없지만 응용 프로그램에 따라 다릅니다. 다른 스레드에 실행 기회가 주어집니다. 모든 시스템 리소스를 처리하는 유일한 스레드 인 경우 UI 스레드와 다른 스레드가 충분한 CPU 시간을 확보 할 수 없으므로 장치가 일반적으로 느려집니다. [busy waiting] (https://secure.wikimedia.org/wikipedia/en/wiki/Busy_waiting)을보십시오. –

+0

# 1 또는 # 3 접근 방법을 시도 했습니까? 'wait/notify'는 소비자 - 생산자 문제에 대한 일반적인 접근법입니다 - 제가 연계 된 튜토리얼을보십시오. 그리고 # 1의 코드는 거의 완성되었습니다. 쓰기 로그인을 거기의'run()'메소드로 옮기면됩니다. 그래도 여전히 도움이되지 않으면 문제가 다른 곳에 있습니다. –

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.... 
} 
+0

또한보십시오 [분리되는 실에있는 Acclerometer 감지기] (http://stackoverflow.com/a/17513504/192373) –

관련 문제