在其他类中获取 AsyncTask 的输出

Posted

技术标签:

【中文标题】在其他类中获取 AsyncTask 的输出【英文标题】:Getting output of AsyncTask in other class 【发布时间】:2020-08-17 12:16:08 【问题描述】:

我正在学习android开发,我必须检查服务器上是否存在文件。

我正在使用以下代码

public class CheckReportExists extends AsyncTask<String, Void, Boolean>

    Boolean fileExists = false;

    public CheckReportExists() 

    

    public Boolean CheckReportExists1(String download_url)
        execute(download_url);
        return fileExists;
    

    @Override
    protected void onPreExecute() 
        //display progress dialog.

    
    @Override
    protected Boolean doInBackground(String... params) 
        try 
            HttpURLConnection.setFollowRedirects(false);
            HttpURLConnection con =  (HttpURLConnection) new URL(params[0]).openConnection();
            con.setRequestMethod("HEAD");
            int response = con.getResponseCode();
            if(response == HttpURLConnection.HTTP_OK)
                fileExists = true;
            
         catch(Exception e)

        
        return fileExists;
    

    @Override
    protected void onPostExecute(Boolean result) 
        // dismiss progress dialog and update ui
        //super.onPostExecute(result);
    


要调用它,我使用以下代码

     CheckReportExists cre = new CheckReportExists();
     Boolean fileExists = cre.CheckReportExists1(download_url);
     if(fileExists) 
          builder.setPositiveButton("Download Report", new DialogInterface.OnClickListener() 
          @Override
          public void onClick(DialogInterface dialog, int which) 
                 new DownloadTask(Results.this, download_url);
          
          );
      else
            builder.setPositiveButton("Report not ready yet", new DialogInterface.OnClickListener() 
                   @Override
                    public void onClick(DialogInterface dialog, int which) 

                    
             );
      

但是这段代码不是工作时间我得到AlertDialog 带有“报告尚未准备好”按钮,即使文件存在于服务器上。

谢谢。

【问题讨论】:

CheckReportExists1() 将始终返回 false 值,因为它不会等到 AsyncTask 完成其工作 【参考方案1】:

类似这样的:

 CheckReportExists cre = new CheckReportExists() 
     @Override
     protected void onPostExecute(Boolean result) 
        super.onPostExecute(result);
        // RIGHT HERE is where you can add your code to handle the result
     
 ;
 // CheckReportExists1 is no longer a good name because it's not
 // returning a value.  It just starts the process.
 cre.CheckReportExists1(download_url);

【讨论】:

这是anonymous class BTW【参考方案2】:

CheckReportExists1() 将始终返回 false 值;那是因为它在 UI 线程中运行,并且不会等到 AsyncTask 完成其后台工作。所以它总是会返回它的初始分配值false

要解决这个问题,您可以创建一个带有回调方法的侦听器接口,该方法接受一个指示文件是否存在的Boolean。并在后台工作结束后真正确保文件存在或不存在时触发此回调。

所以修改你的代码:

监听器接口:

interface OutputListener 
    void checkFile(Boolean exists);

异步任务:

public class CheckReportExists extends AsyncTask<String, Void, Boolean>

    Boolean fileExists = false;
    OutputListener listener;

    public CheckReportExists() 

    

    public void CheckReportExists1(String download_url, OutputListener outputListener)
        execute(download_url);
        listener = outputListener;
    

    @Override
    protected void onPreExecute() 
        //display progress dialog.

    
    @Override
    protected Boolean doInBackground(String... params) 
        try 
            HttpURLConnection.setFollowRedirects(false);
            HttpURLConnection con =  (HttpURLConnection) new URL(params[0]).openConnection();
            con.setRequestMethod("HEAD");
            int response = con.getResponseCode();
            if(response == HttpURLConnection.HTTP_OK)
                fileExists = true;
            
         catch(Exception e)

        
        return fileExists;
    

    @Override
    protected void onPostExecute(Boolean result) 
        if (listener != null)
            listener.checkFile(result);

        // dismiss progress dialog and update ui
        //super.onPostExecute(result);
    


AsyncTask 用法:

CheckReportExists cre = new CheckReportExists();
cre.CheckReportExists1(download_url, new OutputListener() 
            @Override
            public void checkFile(Boolean exists) 
                if(fileExists) 
                    builder.setPositiveButton("Download Report", new DialogInterface.OnClickListener() 
                        @Override
                        public void onClick(DialogInterface dialog, int which) 
                             new DownloadTask(Results.this, download_url);
                        
                    );
                 else 
                    builder.setPositiveButton("Report not ready yet", new DialogInterface.OnClickListener() 
                           @Override
                            public void onClick(DialogInterface dialog, int which) 

                            
                     );
                

            
        );

【讨论】:

以上是关于在其他类中获取 AsyncTask 的输出的主要内容,如果未能解决你的问题,请参考以下文章

我如何从AsyncTask中的数据库类中获取对象?

获取其他类中的变量

如何从android中的AsyncTask类中获取数据?

AsyncTask - 等待其他 Asynctask 的执行

ANDROID:在其他类中获取纬度和经度,但值变为0.0

Android中AsyncTask的通用类?