0

私のAndroidプロジェクト(センサーのキャプチャ、マルチスレッド処理、およびcsvファイルへの出力書き込み)は、Nexusおよびその他のデバイス(4.4キットカット、4.3 / 4.2 Jellybean)で正常に動作しています...しかし、Sony Xperia Zでテストすると、クラッシュします.. .

ヒント: デバッグ モードで実行してもクラッシュしません ....

データがキャプチャされ、処理され、出力csvファイルに書き込まれ、数秒実行した後にクラッシュが発生するため、マルチスレッドの問題に関連していると思います...

私が忘れたソニーの実装に固有のものはありますか?

LogCat は https://gist.github.com/erwin/10535096にあります。

ヒントをありがとう....ソニーのデバイスで実行する必要があります...

2 つのスレッドを開始するメインの SwimActivity は次のとおりです: samplingThread (センサー データをキャプチャ リストにキャプチャ)

        public class SwimActivity extends Activity implements OnSeekBarChangeListener  {    

        private SamplingThread          samplingThread;
        private InterpolationThread     interpolationThread;

        public volatile ArrayList<LinkedList<CapturedEvent>> captures = new ArrayList<LinkedList<CapturedEvent>>();  // filled by sampligThread
        public volatile ArrayList<LinkedList<CapturedEvent>> sensors = new ArrayList<LinkedList<CapturedEvent>>();   
        public volatile LinkedList<InterpolatedEvent> cachedData = new LinkedList<InterpolatedEvent>();

        class SwimHandler extends Handler {    // handle messages from interpolationThread
            @Override
            public void handleMessage(Message msg) {
              super.handleMessage(msg);
              if (this != null) {
                    Bundle bundle = msg.getData();
                    Integer msgKey = bundle.getInt("msgKey");               
                    switch(msgKey){
                    case SENSORS_READY:
                        showToast("all sensors ready..");
                        sensorsReady();
                        break;
                    case SAMPLING:
                        showToast("sampling..");
                        break;
                    case SAMPLING_COMPLETED:
                        samplingCompleted();
                        break;
                    }
              }

            }
        }
        public final SwimHandler mHandler = new SwimHandler();


        private void startSampling() {  //  user hit the start button on UI
            //  init output csv file
            // ....
                FileWriter fileWriter = new FileWriter( captureFileName, false );
                captureFile = new PrintWriter( fileWriter );

            // initialize ArrayList 
            // ........

            Log.i(TAG, "starting samplingThread");
            samplingThread = new SamplingThread(this, captures);
            samplingThread.setPriority( Thread.NORM_PRIORITY);
            samplingThread.start();  
        } 


        private void sensorsReady() {  // when message 'SENSORS_READY' received from interpolationThread
            cachedData.clear();

            Log.i(TAG, "sensors ready, starting interpolationThread");
            interpolationThread = new InterpolationThread(SwimActivity.this, captures, sensors, cachedData, ...  other params );
            interpolationThread.setPriority( Thread.NORM_PRIORITY + 1);
            interpolationThread.start();                            
         }
    }

およびinterpolationThread(キャプチャされたデータを処理し、補間されたデータをcsvファイルに書き込みます)

        public class InterpolationThread extends Thread {
        // .....
        ArrayList<LinkedList<CapturedEvent>> captures;
        ArrayList<LinkedList<CapturedEvent>> sensors;
        LinkedList<InterpolatedEvent> cachedData;

        public InterpolationThread(SwimActivity activity, ArrayList<LinkedList<CapturedEvent>> ceList ..... {
            // ... init params
            running = true;
        }

        @Override
        public void run() {
            lastMessageTime = SystemClock.elapsedRealtime();  // millis
            if (interpolationTime == 0 ) { setInitialInterpolationTime(); }     
            lastMessageTime = SystemClock.elapsedRealtime();  // millis
            if (interpolationTime == 0 ) { setInitialInterpolationTime(); }     
            while(running ){                
                    interpolatedSensorData = interpolateAllSensors();    // interpolate && set sensorStatus - Vector<Integer>
                    addInterpolatedDataToCache(interpolatedSensorData);
                    processCachedData();
                    cleanUpCachedData();  // write completed interpolations into csv log file
            }
            running = false;
        }
        public void interrupt() {
            running = false;
            if( captureFile != null )
                captureFile.close();
        }

        // other processing methods

        public void cleanUpCachedData() {
            ListIterator<InterpolatedEvent> cacheIterator = cachedData.listIterator();
            while(cacheIterator.hasNext()) {
                InterpolatedEvent cachedEvent = cacheIterator.next(); 
                Vector<Vector3> cachedEventValues = cachedEvent.values;  // all sensors
                if (allInterpolationsCompleted(cachedEventValues)) { // all sensors got interpolated data
                    writeInterpolatedDataIntoLogFile(cachedEventValues);
                    cacheIterator.remove();  // remove current interpolatedEvent from cache()
                }
            }
        }

        public void writeInterpolatedDataIntoLogFile(Vector<Vector3>interpolatedSensorData) {   
            // .....        
            elapsedLogTime += samplingRate; 
            Vector3 orientation = calculateOrientation(interpolatedSensorData);
            // ...
            String data = "" + elapsedLogTime;              
            Iterator<Vector3>  sensorIterator = interpolatedSensorData.iterator();  
            while(sensorIterator.hasNext() ) {
                Vector3 values = (Vector3) sensorIterator.next();
                int sensorIndex = interpolatedSensorData.indexOf(values);
                if (sensorIndex == 1 && !gyro)  {
                    Vector3 zeroValues = new Vector3(); // insert gyro = zero
                    for (int i = 0; i < 3; i++) { data = data + ";" + nf.format(zeroValues.toArray()[i]);}      //gyro  0   
                    for (int i = 0; i < 3; i++) { data = data + ";" + nf.format(zeroValues.toArray()[i]);}      // linearAccel 0        
                } else if (sensorIndex == 2 && !linearAccel)  {
                    Vector3 zeroValues = new Vector3(); // insert gyro = zero
                    for (int i = 0; i < 3; i++) { data = data + ";" + nf.format(zeroValues.toArray()[i]);}                  
                    for (int i = 0; i < 3; i++) { data = data + ";" + nf.format(values.toArray()[i]); } // add linearAccel data     
                }

                else 
                    for (int i = 0; i < 3; i++) { data = data + ";" + nf.format(values.toArray()[i]); }                     
            }   
            for (int i = 0; i < 3; i++) { data = data + ";" + nf.format(orientation.toArray()[i]); }

            captureFile.println( data );        
            }
        }
    }
4

1 に答える 1

0

以前の run() メソッドが Nexus (Android4.4) で正常に動作していた理由はわかりませんが、 samplingThread の run() メソッドを変更しました。

以前の方法 (Sony Xperia (Android 4.3) で実行されていない場合:

@Override
public void run() {
    while(running ){}
    running= false;
}

修正された方法(すべてのデバイスで正常に動作):

Object LOCK = new Object(); // just something to lock on
@Override
public void run() {
    while(running ){ 
        synchronized (LOCK) {
            LOCK.notifyAll();
        }
    }
    running= false;
}

考慮されていないように見えるため、スレッドの優先度設定も削除しました...サンプリングされたデータを取得するために、samplingThreadがinterpolationThreadにしばらく時間を与えていなかったようです。

于 2014-04-14T07:28:57.973 に答える