簡體   English   中英

在Android代碼中引入任何形式的循環時,不會加載Main.xml

[英]Main.xml not loading when a loop of any sort introduced in Android code

請參考以下代碼,該代碼從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()時,此代碼非常setValues() 但是,一旦我引入了循環,直到循環完成, main.xml (或屏幕上的任何內容)都不會加載。 我認為這與活動生命周期有關,但是無論我在哪里放置代碼,都無法正常工作。 本質上,我希望每次調用setValues()都保持更新。 10次​​迭代循環僅用於測試概念。

您需要了解UI線程的工作原理,以了解為什么在循環完成之前看不到任何內容。 UI線程包含一個消息循環,在該消息循環中,消息(您可以將它們視為小的代碼塊)推入並串行執行(一次1條)。 當UI線程運行您的代碼時,它將執行您所要求的所有操作,但是屏幕上的值將被“發布”,或發送到消息循環中,以在下一個可用時間實際放置在屏幕上。 您不應該在UI線程上執行長時間運行的操作,這就是Android系統采用多種方式處理長時間運行的操作的原因。 最常見的情況是使用AsyncTask。

絕對不要在UI線程上執行Http調用,實際上,這將在運行Honeycomb或更高版本的設備上失敗(除非您在代碼中引入了一些技巧)。

您應該將http調用放在doInBackground方法的AsyncTask中。 然后設置onPostExecute方法,您可以調用UI方法(.setText方法)。 您需要將所有數據放入某種數據結構中,例如doInBackground方法中的ArrayList。

一個非常有趣的問題,據我的一位前輩說,當您請求更改或重繪UI時,將調用GPU進行更改,因此,在執行第一行進行更改時,會通知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

並查看是否在每個通話中都進行了更改(我知道這不是您的解決方案,但這只是出於了解目的)

如果我建議一個解決方案,那么我會說使用ayn任務來進行UI更新,因為從3.0 Honeycomb開始,對UI的任何更改都無法從主線程完成

請參閱此http://www.vogella.com/articles/AndroidPerformance/article.html進行異步任務

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM