【问题标题】:AsyncTask freezing both its thread and the UI thradAsyncTask 冻结其线程和 UI 线程
【发布时间】:2017-08-14 15:12:57
【问题描述】:

我创建了一个扩展AsyncTask 的类,以便从我的应用程序向我的服务器发送 POST 请求。它一直工作到现在。我没有改变任何东西,但是当我尝试执行它时,它突然冻结了 UI 线程和它自己的线程。

我尝试使用Log.d() 找出它在冻结之前将你带到哪里,结果发现它在调用doInBackground() 之后立即冻结。

我也试过改变这个...

String result = new AsyncPost().execute(params).get();

到这里……

AsyncTask task = new AsyncPost();
task.execute();
String result = task.get();

这与我给它的参数无关,因为无论传递什么参数它都会冻结。

我也尝试使用 Postman 来检查我的服务器是否正常工作(确实如此),所以这也不是服务器端问题。

这是我的AsyncTask 课程。抱歉,代码量过多,但我无法弄清楚它的哪个特定部分是坏的,因为到目前为止它都在工作。

public class AsyncPost extends AsyncTask<Object, Integer, String> {
    @Override
    protected String doInBackground(Object ... params){
        //android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);

        Object urlObj = params[0];
        Object argsObj = params[1];

        String urlStr = (String) urlObj;
        Map<String, String> args = (Map<String, String>) argsObj;

        URL url;
        HttpsURLConnection http = null;

        byte[] out = null;
        int len = 0;
        Log.d("POST", "STARTED");

        try {
            url = new URL(urlStr);

            http = (HttpsURLConnection) url.openConnection();
            http.setRequestMethod("POST");
            http.setDoOutput(true);

            StringJoiner sj = new StringJoiner("&");

            for (Map.Entry<String, String> entry : args.entrySet()) {
                sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "="
                        + URLEncoder.encode(entry.getValue(), "UTF-8"));
            }

            out = sj.toString().getBytes(StandardCharsets.UTF_8);
            len = out.length;

            http.setFixedLengthStreamingMode(len);
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

            http.connect();
            Log.d("POST", "CONNECTED");
        }

        catch (Exception e){
            e.printStackTrace();
            return null;
        }

        try (OutputStream os = http.getOutputStream()){
            os.write(out);
        }

        catch (Exception e){
            e.printStackTrace();
            return null;
        }

        try {
            Log.d("POST_RESPONSECODE", Integer.toString(http.getResponseCode()));
            BufferedReader responseReader = new BufferedReader(new InputStreamReader(http.getInputStream()));
            StringBuilder responseBuilder = new StringBuilder();
            String response;

            while ((response = responseReader.readLine()) != null){
                responseBuilder.append(response);
            }

            Log.d("POST", responseBuilder.toString());

            return responseBuilder.toString();
        }

        catch (Exception e){
            e.printStackTrace();
            return null;
        }

        finally{
            http.disconnect();
        }
    }

    @Override
    public void onProgressUpdate(Integer ... progress){
        Log.d("POST", "PROGRESS = " + Integer.toString(progress[0]));
    }
}

我应该怎么做才能解决这个问题?

我应该使用AsyncTask 来完成这项任务吗?我试过使用Thread,但这也冻结了我的用户界面。

我看过其他问题,但他们似乎都在这样做......

Object result = new AsyncTask().get();

这是造成他们问题的原因,这不适用于我。

【问题讨论】:

    标签: java android multithreading android-asynctask


    【解决方案1】:

    在 AsyncTask 上调用 get() 基本上会阻止该线程上的执行,在您的情况下是主线程。 而不是你想要做的是在你的 AsyncTask onPostExecute() 方法中实现 (https://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute(Result))

    【讨论】:

      【解决方案2】:

      如果您不想在主线程上等待结果,则需要在覆盖的onPostExecute 方法中使用AsyncPost 类使用的接口。不要忘记让接收类实现它:

      AsyncPostListener

      interface AsyncPostListener {
          void continueWith(String result);
      }
      

      主要活动

      @Override
      public void continueWith(String results) {
          //continue your logic here
      }
      

      异步发布

       public class AsyncPost extends AsyncTask<Object, Integer, String> {
          private AsyncPostListener listener;
          ....
          public AsyncPost(AsyncPostListener listener){
              this.listener = listener;
          }
      
          @Override
          protected void onPostExecute(String s) {
              super.onPostExecute(s);
              if(listener != null)
                  listener.continueWith(s);
          }
      }
      

      用法:

      AsyncPost ap = new AsyncPost(this);
      

      【讨论】:

      • 我已经添加了您的更改,除了 AsyncPostlistener 始终为空之外,它似乎有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 2020-01-05
      • 2015-03-17
      • 1970-01-01
      相关资源
      最近更新 更多