【问题标题】:AsyncTask fails when calling it more than once (happens only on older version of android)AsyncTask 在多次调用时失败(仅在旧版本的 android 上发生)
【发布时间】:2016-10-12 17:41:51
【问题描述】:

所以我试图从谷歌文档下载 3 张。 我使用https://spreadsheets.google.com/tq?key=(link...) 来获取txt 文件。 要下载每个文件,我使用 AsynchTask 类。

该应用仅下载第一个文件。之后,它只是失败并显示 HTTP/1.1 302 Moved Temporarily 消息。

仅当我使用具有 API 16 (4.1.2) 的旧手机时才会发生这种情况。它不会发生在较新的或我的模拟器上。

这是我的 AsynchTask 类代码

public class DownloadSheet extends AsyncTask<String, Void, String>{
    private AsyncResult callback;

    public DownloadSheet(AsyncResult callback){
        this.callback = callback;
    }


    @Override
    protected String doInBackground(String... urls) {
        try{
            return downloadUrl(urls[0]);
        }catch (IOException e){
            return "Unable to download sheet.";
        }
    }

    @Override
    protected void onPostExecute(String result){
        //removes the unnecessary parts from the response and construct a JSON
        int start = result.indexOf("{", result.indexOf("{") + 1);
        int end = result.lastIndexOf("}");
        Log.d("Ints: ",start +" "+ end);
        Log.d("Result",result);
        String jsonResponse = result.substring(start, end);
        try {
            JSONObject table = new JSONObject(jsonResponse);
            callback.onResult(table);
        }catch (JSONException e){
            e.printStackTrace();
        }
    }

    private String downloadUrl(String urlString) throws IOException {
        InputStream is = null;

        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(15000 /* milliseconds */);
            conn.setConnectTimeout(60000 /* milliseconds */);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            int responseCode = conn.getResponseCode();
            is = conn.getInputStream();

            String contentAsString = convertStreamToString(is);
            return contentAsString;
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }



    private String convertStreamToString(InputStream is){
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try{
            while ((line = reader.readLine()) != null){
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try{
                is.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

这是我调用类的 MainActivity(我在 onCreate 上调用此方法)

private void downloadSheet(){

    new DownloadSheet(new AsyncResult() {
        @Override
        public void onResult(JSONObject object) {
            mLeagues.add(processJsonLeague("England Championship",object));
        }
    }).execute("https://spreadsheets.google.com/tq?key=1a5bkkyEtY0xs-BmCLDrhntSneion_h5miqEDfsve-C4");

    new DownloadSheet(new AsyncResult() {
        @Override
        public void onResult(JSONObject object) {
            mLeagues.add(processJsonLeague("Premier League",object));
        }
    }).execute("https://spreadsheets.google.com/tq?key=1X5oGmyH4qbPQcGroR2RhwMX_RkoVYcmev4fLu9Rs9Ig");


    new DownloadSheet(new AsyncResult() {
        @Override
        public void onResult(JSONObject object) {
            mLeagues.add(processJsonLeague("England League 1",object));
        }
    }).execute("https://spreadsheets.google.com/tq?key=1hRiDvdLPkQEdTSVxmWEoWXjmCFQodNjMNYi3Fd7yYn0");

    Log.d("Length",mLeagues.size() + "");
}

processJsonLeague 方法代码

private League processJsonLeague(String leagueName,JSONObject object) {
    ArrayList<Team> teams = new ArrayList<>();
    try {
        JSONArray rows = object.getJSONArray("rows");


        for (int r = 0; r < rows.length(); ++r) {
            JSONObject row = rows.getJSONObject(r);
            JSONArray columns = row.getJSONArray("c");

            String name = columns.getJSONObject(0).getString("v");
            double hGoalAv = columns.getJSONObject(1).getDouble("v") / 4;
            double aGoalAv = columns.getJSONObject(2).getDouble("v") / 4;
            teams.add(new Team(name, hGoalAv, aGoalAv));
            Log.d("Team", name + " " + hGoalAv + " " + aGoalAv);
        }



    } catch (JSONException e) {
        e.printStackTrace();
    }
    return new League(leagueName, teams);
}

就是这样。让我困惑的是,这个问题只发生在我的旧设备上。

这是我的 downloadUrl() 方法的结果

HTTP/1.1 302 Moved Temporarily
          Content-Type: text/html; charset=UTF-8
          Cache-Control: no-cache, no-store, max-age=0, must-revalidate
          Pragma: no-cache
          Expires: Mon, 01 Jan 1990 00:00:00 GMT
          Date: Thu, 13 Oct 2016 07:06:18 GMT
          Location: https://docs.google.com/spreadsheets/d/1X5oGmyH4qbPQcGroR2RhwMX_RkoVYcmev4fLu9Rs9Ig/gviz/tq
          P3P: CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info."
          P3P: CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info."
          Content-Encoding: gzip
          X-Content-Type-Options: nosniff
          X-XSS-Protection: 1; mode=block
          Server: GSE
          Set-Cookie: NID=88=VmfjKSOqoHkZboIam76WYvlMIpaiTwKSh5sdHZiAstu8fcYs2OXQZOkRQXckYS1ZHiaU-hOlIKUm2bAxfv82dz7ACi6jN0wIJzJm6g5ZAuBTwjunKGwoESg-SufmHiwF;Domain=.google.com;Path=/;Expires=Fri, 14-Apr-2017 07:06:18 GMT;HttpOnly
          Set-Cookie: NID=88=mMkSgEkEYA61zJPS_i2hSHO2oGL8sXgg-mcCwXW1mEbyMx912i1iEWfAXoXqNNYbyN0T_AgKNaPklEWYhqkENhMBFVUacp9yEBdu8HZc6uqbTRjI5RreSUIa39_23kg1;Domain=.google.com;Path=/;Expires=Fri, 14-Apr-2017 07:06:18 GMT;HttpOnly
          Alt-Svc: quic=":443"; ma=2592000; v="36,35,34,33,32"
          Transfer-Encoding: chunked

          00000001

          00000001
          �
          00000001

          00000001
          ��
          00000001
          ��
          00000001
          ��
          00000001
          ��
          00000001
          ��
          00000001
          ��
          00000001
          ��
          00000001
          m
          00000001
          �
          000001
          �
          db
          N�0D��
          �ܳ�*�"7RڦI�D�B�   �d�+j��nP�z\Ñ��vv4�[V��L"Vd���e�TzT�6�9��~�����:��e�W�nD����� z�����HH$��.
          ?��%*�XJ
          ��VT:7�G������p¸�
          �h��Dtz�5:W�bq~{z�r��˯�y����)���e��r?�0��i"� �4�=�
          %��O���,��%����
          0

【问题讨论】:

  • AsyncTask fails when calling it more than once。不,这是一个糟糕的描述。相反,您同时开始三个任务。异步任务的处理方式与旧任务不同。在您的旧版本上,它们确实同时运行。在较新的机器人上,它们是按顺序执行的。
  • 是的,我确实同时给他们三个打电话。明天我会尝试在对方完成后给他们打电话,看看是否是问题所在。如果有人有任何建议,请随时在这里写,我试试看。

标签: java android json http android-asynctask


【解决方案1】:

看看这个问题可能会有所帮助Android SDK AsyncTask doInBackground not running (subclass)

TL;DR AsyncTask 的默认行为在不同版本的 Android 之间发生了变化,在串行和并行执行之间切换。尝试使用.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) 进行并行执行,或使用基于构建版本的条件块进行选择,如上面链接中所述。

【讨论】:

  • 感谢您的建议!明天会看它并告诉你进展如何:P
  • 看到帖子并将我的执行更改为 executeOnExecutor 但没有区别。问题似乎不在并发线程上,因为在我确定第一个下载结束后,我测试了根据我的需求运行第二个下载。看起来我的 downloadUrl() 方法有问题。 HTTP/1.1 302 暂时移动似乎是整个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 2012-09-21
  • 1970-01-01
  • 2014-04-06
  • 1970-01-01
  • 2020-10-14
相关资源
最近更新 更多