2014-03-13 50 views
2

此問題針對Google Drive Android API support team。這可能被認爲是一個錯誤或只是單挑注意。當測試GDAA我碰到的這個問題:新Google Drive Android API - 未完成文件的元數據過早可用

  1. 我創建asynchronyously
  2. 文件已經準備好之前,我進行了搜索,發現通過文件名的文件
  3. 管理檢索它的元數據文件沒有問題
  4. 嘗試使用元數據標誌炸燬了(顯然)

的一點是:不應搜索文件或元數據檢索顯示,文件還沒有準備好/不存在了嗎?或者有沒有一種方法來檢查?

下面是代碼片段來演示該問題(簡化 - 不是一個生產水平代碼)

原始#1創建一個文件非同步

void createFileAsync(final DriveFolder fldr, final String name, 
                  final String mime, final byte[] buff) { 
    final DriveId dId = fldr.getDriveId(); 
    Drive.DriveApi.newContents(_gac).setResultCallback(new ResultCallback<ContentsResult>() { 
     @Override public void onResult(ContentsResult rslt) { 
     if (!rslt.getStatus().isSuccess()) return; 
     DriveFolder folder = Drive.DriveApi.getFolder(_gac, dId); 
     MetadataChangeSet meta = new MetadataChangeSet.Builder() 
                 .setTitle(name).setMimeType(mime).build(); 
     folder.createFile(_gac, meta, rslt.getContents()).setResultCallback(
                  new ResultCallback<DriveFileResult>() { 
      @Override public void onResult(DriveFileResult rslt) { 
      _dFile = rslt.getStatus().isSuccess() ? rslt.getDriveFile() : null; 
      } 
     }); 
     } 
    }); 
    } 

原始#2找到名字的文件 - 與等待

public DriveFile findFirst(String name) { 
    Filter filtr = Filters.and(
     Filters.eq(SearchableField.TRASHED, false), 
     Filters.eq(SearchableField.TITLE, name) 
    ); 
    Query qry = new Query.Builder().addFilter(filtr).build(); 
    MetadataBufferResult rslt = (Drive.DriveApi.query(_gac, qry).await() 
    if (rslt.getStatus().isSuccess()) { 
     MetadataBuffer mdb = null; 
     try { 
     mdb = rslt.getMetadataBuffer(); 
     return Drive.DriveApi.getFile(_gac, mdb.get(0).getDriveId());   
     } finally { if (mdb != null) mdb.close(); } 
    } 
    return null; 
    } 

測試/問題方案:

GoogleApiClient _gac; 

    DriveFolder fldr = Drive.DriveApi.getRootFolder(_gac); 
    byte[] buffer = ("FooBar ").getBytes(); 

    // create a file async 
    DriveFile _dFile = null; 
    createFileAsync(fldr, "foo", "text/plain", buffer); 

    // file is not ready yet, but FOUND and it's metadata VALID (non-null) 
    Metadata md = findFirst("foo").getMetadata(_gac).await().getMetadata(); 

    // any attempt to use Metadata methods 
    // md.isTrashed(), md.getTitle(), ... 
    // blows up until the createFileAsync() is finished 
+0

什麼意思是「沒有準備好」? –

+0

我打電話給createFileAsync()。它立即取回(它是異步的),但是文件實際上是稍後創建的(在createFileAsync()中有兩個級聯的異步回調)。在此期間(文件創建尚未完成),可以通過上面的findFirst()調用找到該文件。如果你在這裏grep'SystemClock.sleep(2000)',你會看到它:https://github.com/seanpjanson/140201-GDAA/blob/master/awaits/MainActivity.java – seanpj

+0

改寫:進入createFileAsync ()和第二個onResult()。在此期間,該應用程序可以調用Drive.DriveApi.query(...)。在這段時間內應該使用Drive.DriveApi.query(...)。await()來找到文件嗎?它被發現並且它的元數據不穩定。 – seanpj

回答

0

我很高興地報告,問題就消失了(通過介入?)。正在創建的文件(異步)上名稱爲的在創建完成之前不會返回有效的元數據。從上面的原始#2簡化的代碼塊:

for (Metadata md : rslt.getMetadataBuffer()) 
    ; // NO md AVAILABLE until the file creation is completed!!! 

正常工作,現在,沒有任何枚舉直到元數據「的文件已準備就緒」。