Java 不能在UI线程上调用Android-await

Java 不能在UI线程上调用Android-await,java,android,wear-os,Java,Android,Wear Os,我正在尝试编写一个Wear OS应用程序,将IMU传感器数据记录为二进制文件并发送到手机 @Override public void onDataChanged(DataEventBuffer dataEvents) { final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents); dataEvents.close(); Log.e("List Size: ", Stri

我正在尝试编写一个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 ;
}
@覆盖
公共无效onDataChanged(DataEventBuffer dataEvents){
最终列表事件=FreezableUtils.freezeitrable(dataEvents);
dataEvents.close();
Log.e(“列表大小:”,String.valueOf(events.Size());
用于(数据事件:事件){
if(event.getType()==DataEvent.TYPE\u已更改){
Log.v(“数据已更改”,”========================================”;
字符串路径=event.getDataItem().getUri().getPath();
if(传感器数据路径等于(路径)){
DataMapItem DataMapItem=DataMapItem.fromDataItem(event.getDataItem());
资产文件资产=dataMapItem.getDataMap().getAsset(“文件”);
WriteToFilesFromAsset(mgoogleapclient,fileAsset);
}
}
}
status.setText(“已接收!!”);
}
私有无效写入来自资产的文件(GoogleAppClient GoogleAppClient,资产){
字符串FileName=“\u Activity.bin”;
File dataFile=新文件(Environment.getExternalStorageDirectory().toString()+“/DataFiles”,FileName);
如果(资产==null){
抛出新的IllegalArgumentException(“资产必须非空”);
}
//下面的一行打断了应用程序
InputStream assetInputStream=Wearable.DataApi.getFdForAsset(GoogleAppClient,asset).Wait().getInputStream();
字节[]缓冲区=新字节[缓冲区大小];
内特比德;
试一试{
FileOutputStream fos=新的FileOutputStream(数据文件);
而((byteRead=assetInputStream.read())!=-1){
fos.write(byteRead);
}
assetInputStream.close();
fos.close();
}
捕获(IOEX异常){
Log.e(“IO”,例如toString());
}
Log.i(“Type”,assetInputStream.toString());
返回;
}
我得到一个错误,说不能在UI线程上调用wait

我发现了类似的问题,但没有一个能解决我的问题

如果你能帮我修复这个错误,我将不胜感激


谢谢大家!

您正在使用的API有一个限制,不允许您从UI(又称主)线程调用wait。Android中有几个API可以做到这一点,以帮助开发者避免做愚蠢的事情。如果您阻止UI线程,操作系统将无法绘制您的应用程序,因此它看起来像挂起给用户,最终将导致错误

在这种情况下,您尝试执行的任务可能需要一段时间,因此您需要退出UI线程并在后台线程中完成操作。有几种方法可以做到这一点。您从
getFdForAsset
返回的
pendingreult
上有一个
setResultCallback
方法,该方法将绕过等待问题。但是,您稍后会执行一些I/O来保存数据,这样也会出现类似的错误,因为您也不应该在IU线程上执行这些操作。您需要将整个操作放在后台线程上

下面是一些用于执行后台任务的文档

试试看

    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();
}

你为什么不换一条线试试呢?我知道很晚了,但非常感谢你!这帮了大忙