我正在尝试编写一个Wear OS应用,该应用将IMU传感器数据记录为二进制文件并将其发送到手机。
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
Log.e("List Size: ", String.valueOf(events.size()));
for (DataEvent event : events){
if (event.getType() == DataEvent.TYPE_CHANGED){
Log.v("Data is changed", "========================");
String path = event.getDataItem().getUri().getPath();
if(SENSOR_DATA_PATH.equals(path)){
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
Asset fileAsset = dataMapItem.getDataMap().getAsset("File");
WriteToFilesFromAsset(mGoogleApiClient, fileAsset);
}
}
}
status.setText("Received!!");
}
private void WriteToFilesFromAsset(GoogleApiClient googleApiClient, Asset asset){
String FileName = "_Activity.bin";
File dataFile = new File(Environment.getExternalStorageDirectory().toString()+"/DataFiles", FileName);
if (asset == null){
throw new IllegalArgumentException("Asset must be non-null");
}
//The line below breaks the app
InputStream assetInputStream = Wearable.DataApi.getFdForAsset(googleApiClient, asset).await().getInputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int byteRead;
try{
FileOutputStream fos = new FileOutputStream(dataFile);
while( (byteRead = assetInputStream.read()) != -1){
fos.write(byteRead);
}
assetInputStream.close();
fos.close();
}
catch(IOException ex){
Log.e("IO", ex.toString());
}
Log.i("Type", assetInputStream.toString());
return ;
}
我收到一条错误消息,说不能在UI线程上调用await。
我在SO上发现了类似的问题,但没有一个能够解决我的问题。
如果您能帮助我修复此错误,我将不胜感激。
谢谢!
答案 0 :(得分:2)
您正在使用的API受到限制,不允许您从UI(AKA主)线程中调用await。 Android中有几种API可以帮助您保护开发人员避免做愚蠢的事情。如果您阻止UI线程,则操作系统将无法绘制您的应用程序,因此它似乎挂在用户面前,最终将导致ANR错误。
在这种情况下,您尝试执行的任务可能需要一段时间,因此您需要退出UI线程并在后台线程中完成操作。有几种方法可以做到这一点。从setResultCallback
返回的PendingResult
上有一个getFdForAsset
方法,可以解决等待问题。但是,您稍后将执行一些I / O来保存数据,这也将给您带来类似的错误,因为您也不应该在IU线程上执行此操作。您需要将整个操作放在后台线程上。
以下是一些用于执行后台任务的文档。 https://developer.android.com/training/best-background
答案 1 :(得分:0)
尝试
private void WriteToFilesFromAsset(GoogleApiClient googleApiClient, Asset asset) {
String FileName = "_Activity.bin";
File dataFile = new File(Environment.getExternalStorageDirectory().toString() + "/DataFiles", FileName);
if (asset == null) {
throw new IllegalArgumentException("Asset must be non-null");
}
new Thread(new Runnable() {
@Override
public void run() {
//The line below breaks the app
InputStream assetInputStream = Wearable.DataApi.getFdForAsset(googleApiClient, asset).await().getInputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int byteRead;
try {
FileOutputStream fos = new FileOutputStream(dataFile);
while ((byteRead = assetInputStream.read()) != -1) {
fos.write(byteRead);
}
assetInputStream.close();
fos.close();
} catch (IOException ex) {
Log.e("IO", ex.toString());
}
Log.i("Type", assetInputStream.toString());
}
}).start();
}