2012-03-31 26 views
2

私はmysqlサーバからgoogleマップの座標のペアをダウンロードする必要があるアプリケーションを使用しています。私は正常にphpと正常なhttpostを使用してこれを行うことができますが、私のアプリは数秒間フリーズします。非同期HTTPポストandroid

サーバが処理を終了して結果を送信するまでフリーズするのを避けるために、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(); 
} 

フリーズを避けるために、非同期ポストに変換するにはどうすればよいですか?

+0

私は(それがあるとして、あなたのコードはコンパイルすらできるかわかりませんが、[ 'EntityUtils.toString(response.getEntity())']を使用してくださいhttp://stackoverflow.com/a/2324739/180740)を使用して、独自のBufferedReader-n-StringBuilderパーティを作成するのではなく、前者はコードが少なく、正しいエラー処理があり、サーバーから送信された文字エンコーディングに従います。 –

答えて

1

あなたはボタンのクリックでこれを行うにしたいと仮定すると:

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

を基本的には、UIが凍結しないように、あなたが別のスレッド(ないあなたのUIスレッド)でIO集約的な操作を入れています。

+0

しばらくお待ちください。お返事ありがとうございます:) – user878813

2

新しいスレッドを開始するだけでなく、本格的な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); 
    } 
} 

新しいクラスの実装を、希望するアクティビティのクラス内に配置します。 AsyncTaskの詳細情報については、このリンクに従ってください。

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

5

を簡単に非同期タスクを実行するために使用することができます素敵なクラス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(); 

追加リソース:

3

android-async-http(http://loopj.com/android-async-http/)ライブラリを使用することをおすすめします。それは、アンドロイド非同期httpの呼び出しをシンプルでエレガントにします。

+1

残念ながら、初心者が、この場合はURLにデータを投稿し、JSONを使用してレスポンスを処理するように、すべてをまとめる方法を理解しやすくするデモがごくわずかです。それはすべてそこにあり、非常に強力でスマートなようですが、いくつかの例が間違いなく助けになるでしょう。 – richey

+1

私はそれを使い、簡単に使い始めることができました。私は、http://loopj.com/android-async-http/の「推奨される使用法」セクションで与えられたコードサンプルから始めました。私は、クッキーを永続させる、SSL(信頼できるものと信頼できないもの)で動作させること、デバイスがオンラインかどうかを確認するためのチェックを追加するなど、特定のことを学び、実行します。このライブラリまたはAndroid APIを使用するかどうかに対処する必要があります。 – krishnakumarp

1

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 
    } 
});