【问题标题】:How to manage async task in Android如何在 Android 中管理异步任务
【发布时间】:2016-05-10 10:05:20
【问题描述】:

在我的活动中,我使用线程调用服务器并接收我放在内部存储中的 XML 响应。

在这个调用之后,我读取这个 xml 文件来解析它并向用户显示这个 xml 文件的信息,但是当我在我的 InputStream 中添加这个文件时,这个 InputStream 是空的。

我猜我的活动会继续简单的执行并且不等待我的线程,所以当我创建我的 InputStream 时,我的 xml 文件不存在。

我使这个模式与我的程序的执行相对应:

Schema here

如何让我的活动等待我的线程结束?我知道冻结主要活动不是一件好事,但我不知道我该怎么做。 我可以在我的线程上有观察者的情况下添加一个等待进度条直到线程结束吗?

PS:我的线程实现了 Runnable

/*************用解决方案编辑*************/

首先,感谢大家的回复,这让我进步了很多。

//In my Activity

MyAsyncTask asyncTask = new MyAsynctask();
asynctask.execute();

//My Async class
public class MyAsynctask extends AsyncTask<Void,Void,Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Toast.makeText(getApplicationContext(), "calling server...", Toast.LENGTH_LONG).show();
    }

    @Override
    protected Void doInBackground(Void... params) {

        //Instance of calling class
        //Method of this instance to call the server and create a file in internal storage 
        //After that my file is stored with the server response
        return null;
    }


    @Override
    protected void onPostExecute(Void result){
        super.onPostExecute(result);

        Toast.makeText(getApplicationContext(), "Data received", Toast.LENGTH_LONG).show();

        FileInputStream inputStream = null;
        inputStream = openFileInput("myFile");                     

        data=XMl.parse(inputStream);                  
    }
}

我希望这篇文章和您的回复会有所帮助。

【问题讨论】:

  • 你应该看看AsyncTask
  • 如果我使用异步任务,我不需要创建线程,我将所有请求方法都放在我的异步任务中?
  • AsyncTask 会为你创建后台线程,它有一个回调onPostExecute(...),当任务完成时在主线程上执行。

标签: java android multithreading


【解决方案1】:
 public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            new DownloadfromInternet().execute(server_url);

        }

// 异步任务类 类 DownloadFromInternet 扩展 AsyncTask {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Shows Progress Bar Dialog and then call doInBackground
    }

    // Download  File from Internet
    @Override
    protected String doInBackground(String... f_url) {

        try {
        //make server call and store file in local
        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }
        return LOCAL_FILE_NAME;
    }


    @Override
    protected void onPostExecute(String local_file_url) {
        // read local_file_url

    }
}

【讨论】:

  • 我必须在我的 Activity 中创建我的 AsyncTask,不是吗?在我的其余代码下方
  • yes ...AsyncTask 将在您的活动中。编辑您的问题并在那里编写代码。
  • @Swodniw 希望您的问题已得到解决,但您仍然可以提出任何疑问......
  • 对我来说没问题,再次感谢。我添加了一部分代码来解释我最终要做什么。
【解决方案2】:

我也认为使用AsnycTask 将适合您的用例。

您可以执行AsyncTask 并继续读取和解析onPostExecute 中的响应。

干杯! :D

【讨论】:

  • 感谢您的帮助,直到现在我都使用了 Thread 并且从未使用过 AsyncTask。
  • 一旦你掌握了窍门,就很简单了。快乐编码。干杯! :D
【解决方案3】:

让您的活动等到执行结束不是一个好主意,因为它会冻结 ui 线程。如果任务太长会抛出 ANR。 您有 2 个选择:

  1. 创建执行异步任务所需的参数和条件 然后调用它,前提是异步任务是您的内部类 活动,执行其余的操作,这取决于您的 异步任务导致异步任务的 onPostExecute 回调。

  2. 创建一个界面,该界面具有帮助您进行交流的方法 从异步任务到您的实现类的结果。这是最好的 测试和/或将异步任务作为外部类的方法。一世 经常使用这种方法。在您的异步任务中定义公共 将侦听器设置为您的界面的方法。进行您的活动 实现接口。完成异步任务后,在 onPostExecute,如果 listener 不为 null,则调用接口方法。在 您在活动中实现的方法,实现与相关的逻辑 异步任务结果。

如果您想对其使用测试,为异步任务设置接口回调总是一个好主意。

【讨论】:

    【解决方案4】:

    我猜我的活动会继续简单的执行并且不等待我的线程,所以当我创建我的 InputStream 时,我的 xml 文件不存在。

    --正确

    我的情况是,我建议您可以在触发请求时启动加载对话框。当您收到响应时,将结果发送到在 UI 线程上运行的处理程序,覆盖它的 handleMessage 方法,这就是您关闭对话框并显示信息的地方。

    或者,使用 AsynTask,这样更方便。

    【讨论】:

      【解决方案5】:

      像这样在您的 Activity(或 Fragment 或...)上使用 AsyncTask。 我通常会实现一个 AsyncResponse 接口,以便更轻松地在不同的活动上重用 AsyncTask:

          MyAsyncTask m = new MyAsyncTask(randomparameters, new AsyncResponse(){
                      @Override
                      public void onSuccess(Object result) { 
                          // Success!! do what you want
                      }
      
                      @Override
                      public void onError() { 
                         // Manage errors here
                      }
                  });
          m.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
      

      如果您使用 m.execute() 而不是 executeOnExecutor 并且您同时有多个 AsyncTask,它们会按顺序执行,如果您使用 executor,它们会并行执行。做你想做的或需要的。

      AsyncTask 类,它还有其他可以覆盖的方法,例如 onPreExecute 等。

      public class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
      
          private AsyncResponse response;
      
          public MyAsyncTask(randomparameters, AsyncResponse response) {
              // Constructor
              this.response = response;
          }
      
          @Override
          protected Boolean doInBackground(Void... params) {
              // Implements your async code (call your server)
          }
      
          @Override
          protected void onPostExecute(Boolean result) {
                  if (result) {
                      // Here you can return the response of the server to the activity
                      response.onSuccess(response);
                  } else {
                      response.onError();
                  }
              }
          }
      

      这里是接口(当然,你可以自定义方法):

      public interface AsyncResponse {
      
          void onSuccess(Object result);
          void onError();
      
      }
      

      关于 AsyncResponse 接口,它是可选的,但我总是实现它并且对我有很大帮助。

      【讨论】:

      • 如果你在实现这个过程中遇到任何问题,可以问我,Async Task 是在 Android 上实现你目标的最佳方式,比 Thread 更好。如果有效,请将答案标记为已接受。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-20
      相关资源
      最近更新 更多