0

次のコードを参照してください。このコードは、PHPスクリプトからいくつかの情報を取得し、それを私の電話に表示します。

package room.temperature;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class RoomTemperatureActivity extends Activity {

    String result = null;
    StringBuilder sb=null;

    TextView TemperatureText, DateText;
    ArrayList<NameValuePair> nameValuePairs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TemperatureText = (TextView) findViewById(R.id.temperature); 
        DateText = (TextView) findViewById(R.id.date); 
        nameValuePairs = new ArrayList<NameValuePair>();
    }

    @Override
    public void onResume() {
        super.onResume();
        //setValues();

        for (int i = 0; i < 10; i++) {
            setValues();
        }
    }

    public void setValues() {

        InputStream is = null;

        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://mywebsite.com/tempscript.php");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
        }

        catch(Exception e)  {
            Log.e("log_tag", "Error in http connection" + e.toString());
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
            sb = new StringBuilder();
            sb.append(reader.readLine());
            is.close();
            result=sb.toString();
        }

        catch(Exception e)  {
            Log.e("log_tag", "Error converting result " + e.toString());
        }

        System.out.println(result);

        String[] values = result.split("&");

        TemperatureText.setText(values[0]);
        DateText.setText(values[1]);

    }
}

このコードは、forループをコメントアウトして、setValues()一度だけ呼び出すとうまく機能します。ただし、ループを導入するとすぐにmain.xml(または画面上の何か)、ループが完了するまでロードされません。アクティビティのライフサイクルと関係があると思いましたが、どこにコードを入れようとしても、うまく機能していません。基本的に、を呼び出すたびに値を更新し続ける必要がありますsetValues()。10回の反復ループは、概念をテストするためだけのものです。

4

2 に答える 2

4

ループが完了するまで何も表示されない理由を理解するには、UIスレッドがどのように機能するかを理解する必要があります。UIスレッドには、メッセージ(メッセージを小さなコードブロックと考えることができます)がプッシュされてシリアルに(一度に1つずつ)実行されるメッセージループが含まれています。UIスレッドがコードを実行すると、要求されたすべてのことを実行しますが、画面上の値は「投稿」されるか、メッセージループに送信されて、次に利用可能な時間に実際に画面に配置されます。UIスレッドで長時間実行される操作を実行することは想定されていません。そのため、Androidシステムでは、長時間実行される操作を処理する複数の方法が考案されています。最も一般的なシナリオは、As​​yncTaskを使用することです。

Http呼び出しはUIスレッドで実行しないでください。実際、これは、ハニカム以降を実行しているデバイスでは失敗します(コードにハックを導入しない限り)。

http呼び出しをメソッドのAsyncTaskに配置する必要がありますdoInBackground。次にonPostExecute、UIメソッド(.setTextメソッド)を呼び出すことができるメソッドを設定します。すべてのデータを、doInBackgroundメソッドのArrayListなどのある種のデータ構造に配置する必要があります。

于 2012-10-26T03:35:57.153 に答える
0

非常に興味深い質問です。私の先輩の1人によると、UIの変更または再描画をリクエストすると、GPUが呼び出されて変更が加えられます。したがって、1行目が実行されて変更が行われると、GPUに通知され、変更が行われます。そして、制御は次の行に戻ります。あなたの場合はループなので、基本的にループが完了するのを待って(ループ内のループ)、再描画または再描画します

だから私はあなたがこれが好きならそれをループに入れる代わりに提案するでしょう

setValues(); // 1st Time
setValues(); // 2nd Time
setValues(); // 3rd Time
setValues(); // 4th Time
setValues(); // 5th Time
setValues(); // 6th Time
setValues(); // 7th Time
setValues(); // 8th Time
setValues(); // 9th Time
setValues(); // 10th Time

呼び出しごとに変更が加えられているかどうかを確認します(これはあなたの解決策ではないことはわかっていますが、目的を理解するためだけのものでした)

そして、解決策を提案する場合は、asynタスクを使用してUIの更新を行うと言います。これは、3.0ハニカム以降、メインスレッドからUIへの変更を行うことができないためです。

非同期タスクについては、このhttp://www.vogella.com/articles/AndroidPerformance/article.htmlを参照してください

于 2012-10-26T05:54:26.310 に答える