Android 在没有 execute() 的情况下调用 AsyncTask().get()?

Android calling AsyncTask().get() without execute()?

我在尝试了解 AsyncTask().get() 的实际工作方式时遇到问题。我知道这是 synchronous 执行,但是:我不知道 execute()get() 是如何连接的。 我从 Google 的文档中获得了这个示例代码:

// Async Task Class
class DownloadMusicfromInternet extends AsyncTask<String, String, String> {

    // Show Progress bar before downloading Music
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d("Task: ", "onPreExecute()");
    }

    // Download Music File from Internet
    @Override
    protected String doInBackground(String... f_url) {
       for (int i = 0; i < 100; i++){
           try {
               Thread.sleep(100);
               Log.d("Task: ", String.valueOf(i));
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
        return null;
    }

    // While Downloading Music File
    protected void onProgressUpdate(String... progress) {
        // Set progress percentage
        Log.d("Task: ", "onProgressUpdate()");
    }

    // Once Music File is downloaded
    @Override
    protected void onPostExecute(String file_url) {
        Log.d("Task: ", "onPostExecute()");
    }
}

现在,从 button.onClick() 我用 3 种方式称呼它:

new DownloadMusicfromInternet().execute("");//works as expected, the "normal" way


//works the normal way, but it's synchronous
try {
   new DownloadMusicfromInternet().execute("").get();
} catch (InterruptedException e) {
   e.printStackTrace();
} catch (ExecutionException e) {
   e.printStackTrace();
}

//does not work
try {
  new DownloadMusicfromInternet().get();
} catch (InterruptedException e) {
  e.printStackTrace();
} catch (ExecutionException e) {
  e.printStackTrace();
}

我很困惑 execute() 究竟是如何触发 doInBackground() 然后立即 returns 如果 get() 被调用,而 get() 没有效果在 doInBackground() 上。

execute() 立即安排内部 FutureTask(通常在内部 Executor 上)和 returns。

get() 只是在这个内部 future 上调用 FutureTask.get(),即它等待(如果需要)结果。

所以先调用 get() 而不调用 execute() 会无限期地等待,因为结果永远不会可用。

正如您所提到的,当以正常方式使用时,根本不需要 get(),因为结果在 onPostExecute() 中处理。在我试图理解你的问题之前,我什至不知道它的存在