[英]Android Deprecated Annotation is deprecated, what's the replacement?
[英]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.