我有一个简单的Android应用程序。主要活动在内部设备存储上查找文件。之后会发生什么取决于文件是否存在。这个序列工作正常,因为整个执行是同步的。
如果我现在使用Google Drive API,则所有文件访问都是异步的,主要活动会继续,而不会等待我的搜索结果...
我发现没有办法强迫'同步行为。 UI线程中不允许同步调用Google API。
而且,在AsyncTask中执行此类调用会导致同样的问题......
关于如何处理这种情况的任何想法?
问候,
洛朗
-------------------------编辑------------------------ ----------
我尝试了几种选择,但它们都会产生相同的结果
主要活动和用于查找我的文件的asynctask都被阻止了
知道为什么以及该怎么做?
主要活动代码:
if (!TermsOfUseAgreementHandler.mTermsOfUseAgreed) {
Log.i(mTag, "Terms of use agreement needs to be checked");
mCountDownLatch = new CountDownLatch(1);
TermsOfUseAgreementSearchTask searchAgreementTask = new TermsOfUseAgreementHandler().new TermsOfUseAgreementSearchTask();
// Start the async task to look for agreement file using parallel execution
searchAgreementTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
try {
// Block the main thread so that the task gets a chance to perform its Google Drive access...
mCountDownLatch.await(); // MAIN ACTIVITY HANGS HERE !
} catch (InterruptedException e) {
Log.e(mTag, "Failed to look for user agreement file", e);
}
// The async task should have finished (and decreased mCountDownLatch so that await returns)
// At this moment, the result should be available for the main activity in mTermsOfUseAgreed...
if (!TermsOfUseAgreementHandler.mTermsOfUseAgreed)
TermsOfUseAgreementHandler.checkTermsOfUse(this);
}
AsyncTask代码:
protected Boolean doInBackground(Void... params) {
Log.i(MainActivity.mTag, "Looking for user agreement file");
// Look for the agreement file with synchronous Google Drive API access
Query lookForAgreement = new Query.Builder().addFilter(Filters.eq(SearchableField.TITLE, mTermsOfUseAgreementFile)).build();
MetadataBuffer result = Drive.DriveApi.getAppFolder(MainActivity.mGoogleApiClient).queryChildren(MainActivity.mGoogleApiClient, lookForAgreement).await().getMetadataBuffer(); // ASYNCTASK HANGS HERE !
mTermsOfUseAgreed = result != null
&& result.getCount() != 0
&& result.get(0) != null
&& result.get(0).getTitle() != null
&& result.get(0).getTitle().equals(mTermsOfUseAgreementFile);
// Now that the result is available, decrease the countDownLatch so that the main activity may continue...
MainActivity.mCountDownLatch.countDown();
return mTermsOfUseAgreed;
}
------------------------- EDIT 2 -------------------- --------------
我还尝试将驱动API的连接从主活动移动到asynctask,如驱动器API示例link中所示。
我仍然得到相同的结果但问题现在是连接,因为从不调用相关的回调监听器......
public class TermsOfUseAgreementSearchTask extends AsyncTask<Void, Void, Boolean> {
private GoogleApiClient mClient = null;
final private CountDownLatch latch = new CountDownLatch(1);
public TermsOfUseAgreementSearchTask(Context context) {
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(context)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addScope(Drive.SCOPE_APPFOLDER);
mClient = builder.build();
mClient.registerConnectionCallbacks(new ConnectionCallbacks() {
@Override
public void onConnected(Bundle arg0) {
Log.i(MainActivity.mTag, "Connected");
latch.countDown();
}
@Override
public void onConnectionSuspended(int arg0) {}
});
mClient.registerConnectionFailedListener(new OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult arg0) {
Log.i(MainActivity.mTag, "Connection failed");
latch.countDown();
}
});
}
@Override
protected Boolean doInBackground(Void... params) {
Log.i(MainActivity.mTag, "Connect to drive API");
mClient.connect();
try {
Log.i(MainActivity.mTag, "Wait for connection");
latch.await(); // ASYNC TASK HANGS HERE !
} catch (InterruptedException e) {
return false;
}
if (!mClient.isConnected()) {
return false;
}
try {
Log.i(MainActivity.mTag, "Looking for user agreement file");
// Look for the agreement file with synchronous Google Drive API access
Query lookForAgreement = new Query.Builder().addFilter(Filters.eq(SearchableField.TITLE, mTermsOfUseAgreementFile)).build();
MetadataBuffer result = Drive.DriveApi.getAppFolder(mClient).queryChildren(mClient, lookForAgreement).await().getMetadataBuffer();
mTermsOfUseAgreed = result != null
&& result.getCount() != 0
&& result.get(0) != null
&& result.get(0).getTitle() != null
&& result.get(0).getTitle().equals(mTermsOfUseAgreementFile);
// Now that the result is available, decrease the countDownLatch so that the main activity may continue...
//MainActivity.mCountDownLatch.countDown();
return mTermsOfUseAgreed;
} finally {
mClient.disconnect();
}
}
}