2012-03-31 10 views
0

私は比較的新しいAndroid開発者です。これを行う方法を理解できません。私はすべてのフォーラムを通して見てきました、私はいくつかの進歩を遂げましたが、私はまだここにいます。 私がしたいのは、WebページにPOST要求を送信する共通の関数です(POST引数を1つ送信するだけです)、その結果を文字列として返します。 私はここにメインスレッドAsyncでHttpPostを送信して文字列を取得

public class AppActivity extends Activity { 
    HTTPPostData PostData = new HTTPPostData("id"); 
    PostData.execute(); 
    txtLabel.setText(PostData.Result); 
} 

を持っていると私は私のHTTPPostData非同期クラス

public class HTTPPostData extends AsyncTask<String, Long, Object> { 
String Value = null; 
String Result = null; 

public HTTPPostData(String query) { 
    Value = query; 
    } 

@Override 
protected String doInBackground(String... params) { 
    byte[] Bresult = null; 
     HttpClient client = new DefaultHttpClient(); 
     HttpPost post = new HttpPost("http://www.mypage.com/script.php"); 
     try { 
     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); 
     nameValuePairs.add(new BasicNameValuePair("cmd", Value)); 
      post.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); 
      HttpResponse response = client.execute(post); 
      StatusLine statusLine = response.getStatusLine(); 
      if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK){ 
       Bresult = EntityUtils.toByteArray(response.getEntity()); 
       Result = new String(Bresult, "UTF-8"); 
      } 
     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } catch (Exception e) { 
     } 
     return Result; 
    } 
} 

は、私が同じ活動の内側(この機能を複数回使用するか、同じの他の活動とそれを共有したいいます応用)。私はあなたの助けが必要なので、この時点でちょっと混乱しています。私が理解することは、doInBackground()が完了する前に結果を求めていることです。空の結果が得られます。

これについてあなたの助け

答えて

1

を事前に感謝します:

HTTPPostData PostData = new HTTPPostData("id"); 
PostData.execute(); 
txtLabel.setText(PostData.Result); 

あなたの問題は、それが普通の関数のようにあなたがasynctask治療していることです。ウェブページの読み込みをメインスレッドから外すのは良いことですが、次の命令の結果に依存している場合は、それほどうまくやっていないので、結果を待っているメインプログラムをブロックしています。あなたはAsyncTaskを '火と忘れ'のように考える必要があります。この操作ではいつまで戻ってくるのか分かりません。

ここで行うには良い事はのようになります。

HTTPPostData PostData = new HTTPPostData("id"); 
PostData.execute(); 
txtLabel.setText("Loading..."); 

、その後asynctaskに:

protected void onPostExecute(String result) { 
    txtLabel.setText(result); 
} 

これはあなたのメインスレッドが結果を知らなくても、それはビジネスだやって乗ることができますデータが利用可能になるとすぐに、asynctaskはテキストラベルに結果を設定します。

+0

アプリケーションのさまざまな状況に共通のクラスを使用することをお勧めしましたが、今はそれぞれに非同期クラスを作成する必要があることがわかります。たとえば、数値を取得してSharedPrefferencesに格納されている他の数値と比較し、文字列を取得してTextViewに表示する場合は、これらのアクションのそれぞれについて、ほぼ同じコードを含む別々のクラスを作成する必要があります。私が推測するように、非同期クラスは2回作成できません。 – ali

+0

@ali私はすべてのHttp-to-Stringのものを共通のユーティリティ関数に入れて、インターネットデータを取得したい場所ごとに共通関数を呼び出すベアボーンAsyncTaskを作成し、コールバックの結果を記述するonPostExecuteが必要です。おそらく、複数の種類のasynctaskを作成するのに浪費されているように感じますが、それぞれ異なるコールバックを実行する必要があります。多分もっとクリーンな方法があるかもしれませんが、わかりません。たぶん抽象asynctaskクラスを1つ作成し、それを使用するすべての場所でonPostExecuteをオーバーライドすることができます。 – Tim

+0

それは私がやったことです。ありがとう! – ali

関連する問題