簡體   English   中英

Android 已棄用 Tasks.call - 替換

[英]Android deprecated Tasks.call - replacement

在我的 android 應用程序中,我可以選擇將數據庫備份到 Google Drive。 為此,我正在使用 DriveServiceHelper 類,但我剛剛注意到,在 Android 11 中,不推薦使用 Task.call。

      public Task<FileList> queryFiles() {
    return Tasks.call(mExecutor, () ->
            mDriveService.files().list().setSpaces("drive").execute());
}

從我的 BackupActivity 然后我從backup方法調用queryFiles

  public void backup(View v) {
        driveServiceHelper.queryFiles()
                .addOnSuccessListener(fileList -> {
                  // another code
                })
                .addOnFailureListener(e -> showMsgSnack(getString(R.string.uploaderror)));

我沒有找到任何解決方案來解決這個問題,以避免該類的完全返工。

我試過的:

我試圖替換為可運行的,也可調用的,但它不起作用,因為預計將返回任務,而不是文件列表。

我也嘗試使用TaskCompletionSource

public Task<FileList> queryFiles(int delay) throws IOException, ExecutionException, InterruptedException {

    new Thread(
            new Runnable() {

                @Override
                public void run() {
                    TaskCompletionSource<FileList> taskCompletionSource = new TaskCompletionSource<>();

                    FileList result = null;
                    try {
                        result = mDriveService.files().list().setSpaces("drive").execute();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    FileList finalResult = result;
                    new Handler().postDelayed(() -> taskCompletionSource.setResult(finalResult), delay);

                    return taskCompletionSource.getTask();
                }
            }).start();
    
}

但返回不是來自 void 類型的方法。

我的意思是這樣的:

 public Task<FileList> queryFiles(int delay) throws IOException {
        Task<FileList> retVal;
        final Future<Task<FileList>> future = new FutureValue<>();

        // now run this bit in a runnable
        /*
        TaskCompletionSource<FileList> taskCompletionSource = new TaskCompletionSource<>();
    
        FileList result = mDriveService.files().list().setSpaces("drive").execute();
        new Handler().postDelayed(() -> taskCompletionSource.setResult(result), delay);
    
        return taskCompletionSource.getTask();
        */

        new Thread(
                new Runnable() {

                    @Override
                    public void run() {
                            TaskCompletionSource<FileList> taskCompletionSource = new TaskCompletionSource<>();
    
                            FileList result = mDriveService.files().list().setSpaces("drive").execute();
                            new Handler().postDelayed(() -> taskCompletionSource.setResult(result), delay);
    
                            // and we replace the return statement with something else
                            // return taskCompletionSource.getTask();
                            future.set(taskCompletionSource.getTask());
                   }
        }).start();

       // And block (wait) for future to finish so we can return it, deadlocking the main thread...

//      return future.get();

      //FIXME do either this
//      retVal = future.get();

      // For bonus points, we'll do a timed wait instead -- OR THIS
        try {
            retVal = future.get(30, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            future.cancel(true);
            Log.d(LOG_TAG, "Exception "+e+" happened!", e);
        } catch (InterruptedException | ExecutionException e) {
            Log.d(LOG_TAG, "Exception "+e+" happened!", e);
        }

    return retVal;
}

這應該會讓你走上解決問題的道路。

但是,如果使用Task<>的唯一原因就是您可以向這些方法添加成功/失敗偵聽器 - 我強烈建議您想出更好的東西,它實際上在后台線程而不是您調用它們的線程上運行在。

好的,經過數小時的測試,我嘗試了這個解決方案,現在這似乎有效:(使用 executorService,在 Handler 中需要一個 Looper。)

public Task<FileList> queryFiles() {
    final TaskCompletionSource<FileList> tcs = new TaskCompletionSource<FileList>();
    ExecutorService service = Executors.newFixedThreadPool(1);

    service.execute(
            new Runnable() {
                @Override
                public void run() {

                    FileList result = null;
                    try {
                        result = mDriveService.files().list().setSpaces("drive").execute();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    FileList finalResult = result;
                    new Handler(Looper.getMainLooper()).postDelayed(() -> tcs.setResult(finalResult), 1000);

                }
            });

    return tcs.getTask();

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM