如何应对Google API异步行为?

时间:2017-06-07 12:38:36

标签: android google-drive-api google-drive-android-api



我有一个简单的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();
        }
    }       
}

0 个答案:

没有答案