我的android项目(传感器捕获,多线程处理和输出写入csv文件)在Nexus和其他设备(4.4 kitkat,4.3 / 4.2 Jellybean)上正常工作......但是在Sony Xperia Z上进行测试时,它崩溃...
提示:它没有在调试模式下运行崩溃....
我猜这与多线程问题有关,因为数据被捕获,处理并写入输出csv文件,并且在运行几秒后发生崩溃......
是索尼实施的具体内容我忘记了吗?
可以在https://gist.github.com/erwin/10535096
找到LogCat感谢任何提示......我需要让它在Sony设备上运行......
这里是主要的SwimActivity,它将启动2个线程: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 );
}
}
}
答案 0 :(得分: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来获取采样数据以死锁结束的时间