【问题标题】:Async HTTP post android异步 HTTP 发布 android
【发布时间】:2012-03-31 08:55:34
【问题描述】:

我正在使用一个应用程序,我只需要从 mysql 服务器下载一对谷歌地图坐标。我可以使用 php 和普通的 httpost 成功地做到这一点,但是当我这样做时,我的应用程序会冻结几秒钟。

我读到您需要使 httppost 异步,以避免在服务器完成处理并发送结果之前冻结。

关键是我需要生成一个像普通 httpost 一样的 json 数组。

例如,如果我有这个 httppost。

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

try {
    // Add your data
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
    nameValuePairs.add(new BasicNameValuePair("id", "12345"));
    nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    // Execute HTTP Post Request
    HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
} catch (IOException e) {
    // TODO Auto-generated catch block
}

String result11 = null;
// convert response to string
try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is11, "iso-8859-1"), 8);
    StringBuilder sb = new StringBuilder();
    sb.append(reader.readLine() + "\n");
    String line = "0";
    while ((line = reader.readLine()) != null) {
        sb.append(line + "\n");
    }
    is11.close();
    result11 = sb.toString();
} catch (Exception e) {
    Log.e("log_tag", "Error converting result " + e.toString());
}

// parsing data
try {
    JSONArray jArray1 = new JSONArray(result11);
} catch (JSONException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

如何将其转换为异步帖子以避免冻结?

【问题讨论】:

  • 我不知道你的代码是如何编译的,但请使用EntityUtils.toString(response.getEntity()) 而不是拥有自己的 BufferedReader-n-StringBuilder 派对。前者代码少,错误处理正确,服从服务器发送的字符编码。

标签: android http-post


【解决方案1】:

有一个很好的类AsyncTask 可以用来轻松运行异步任务。如果您将代码嵌入到这样的子类中,您可能会得到这样的结果:

public class FetchTask extends AsyncTask<Void, Void, JSONArray> {
    @Override
    protected JSONArray doInBackground(Void... params) {
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

            // Add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("id", "12345"));
            nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);

            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            sb.append(reader.readLine() + "\n");
            String line = "0";
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            reader.close();
            String result11 = sb.toString();

            // parsing data
            return new JSONArray(result11);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(JSONArray result) {
        if (result != null) {
            // do something
        } else {
            // error occured
        }
    }
}

您可以使用以下命令开始任务:

new FetchTask().execute();

其他资源:

【讨论】:

    【解决方案2】:

    我建议使用 android-async-http (http://loopj.com/android-async-http/) 库。它使 android 异步 http 调用简单而优雅。

    【讨论】:

    • 不幸的是,只有很少的演示可以让新手更容易理解如何将所有内容放在一起,例如在这种情况下将数据发布到 URL 并使用 JSON 处理响应。我知道这一切都在那里,而且似乎非常强大和聪明,但再举几个例子肯定会有所帮助。
    • 我用过它,发现它很容易上手。我从loopj.com/android-async-http 的“推荐用法”部分中给出的代码示例开始。我会在此过程中学习并做某些事情,例如持久化 cookie,使其与 SSL(受信任和不受信任)一起使用,添加检查以查看设备是否在线等。我觉得所有这些问题都会无论你使用这个库还是Android API都必须处理。
    【解决方案3】:

    与其只是启动一个新线程,不如使用一个成熟的 AsyncTask。它提供了更大的控制权。

    private class DoPostRequestAsync extends AsyncTask<URL, Void, String> {
         protected String doInBackground(URL url) {
            //Your download code here; work with the url parameter and then return the result
            //which if I remember correctly from your code, is a string.
            //This gets called and runs ON ANOTHER thread
         }
    
         protected void onPostExecute(String result) {
             //This gets called on the interface (main) thread!
             showDialog("Done! " + result);
         }
     }
    

    将新的类实现放在所需的 Activity 类中。有关 AsyncTask 的更多信息,请点击此链接:

    http://developer.android.com/reference/android/os/AsyncTask.html

    【讨论】:

      【解决方案4】:

      假设您想在单击按钮时执行此操作:

      public void onClick(View v) {
        new Thread(new Runnable() {
              public void run() {
                  //your code here
              }
          }).start();
      }
      

      基本上,您将 IO 密集型操作放在单独的线程(不是您的 UI 线程)中,以便 UI 不会冻结。

      【讨论】:

      • 试了一会儿,我会回答你。非常感谢您的回复:)
      【解决方案5】:

      使用像 ion 这样的异步 http 库。 https://github.com/koush/ion

      将为您处理所有线程和异步样板。

      这是您使用 Ion 的异步代码。简单得多:

      Ion.with(context)
      .load("http://www.yoursite.com/script.php")
      .setBodyParameter("id", "12345")
      .setBodyParameter("stringdata", "AndDev is Cool!")
      .asJsonArray()
      .setCallback(new FutureCallback<JsonArray> {
        void onCompleted(Exception e, JsonArray result) {
          // do something with the result/exception
        }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多