2013-05-30 45 views
0

我有一個類GetWeather.java,它從API中獲取天氣數據。它通過一個單獨的線程定期從我的應用程序的主要活動中調用。該線程命中GetWeather類並將返回的數據發佈到TextView。在Android 4.0中沒有反應類 - 在2.3及以下版本中工作

在任何一種情況下,GetWeather類中返回的數據的System.out.println都顯示確實正在返回數據。

下面是GetWeather.java:

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

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.net.Uri; 
import android.util.Log; 

public class GetWeather { 

    InputStream is = null; 

    JSONArray jArray = null; 
    JSONObject json_data = new JSONObject(); 
    String result = ""; 

    String strTemp = ""; 
    String strWindSpeed = ""; 
    String strWindDir = ""; 
    String strVisibility = ""; 

    String strPosition = ""; 

    public static final Uri KEY_121 = Uri.parse("http://api.worldweatheronline.com/free/v1/weather.ashx"); 
    String strWeatherApiKey = "REMOVED"; 

    public GetWeather(String Location) { 
     strPosition = Location; 
    } 

    public void returnWeather() { 
     try { 
      HttpClient httpclient = new DefaultHttpClient(); 

      HttpPost httppost = new HttpPost(KEY_121 + "?key=" 
        + strWeatherApiKey + "&q=" + strPosition + "&format=json"); 

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

     // convert response to string 
     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        is, "iso-8859-1"), 8); 
      StringBuilder sb = new StringBuilder(); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
      is.close(); 
      result = sb.toString(); 

     } catch (Exception e) { 
      Log.e("log_tag", "Error converting result " + e.toString()); 
     } 
     // parse json data 
     try { 
      JSONObject object = new JSONObject(result); 
      JSONObject weather = object.getJSONObject("data"); 
      JSONArray current_conditions = weather 
        .getJSONArray("current_condition"); 
      for (int i = 0; i < current_conditions.length(); i++) { 
       JSONObject object1 = (JSONObject) current_conditions.get(i); 
       strTemp = object1.getString("temp_C"); 
       strWindSpeed = object1.getString("windspeedMiles"); 
       strWindDir = object1.getString("winddir16Point"); 
       strVisibility = object1.getString("visibility"); 

       // Testing output 
       System.out.println(strTemp); 
       System.out.println(strWindSpeed); 
       System.out.println(strWindDir); 
       System.out.println(strVisibility); 
      } 
     } catch (JSONException e) { 
      Log.e("log_tag", "Error parsing data " + e.toString()); 
     } 
    } 
} 

下面是主要活動的相關代碼:

Runnable updateConsoleRunnable = new Runnable() { 
    public void run() { 
     tvConsole.setMovementMethod(new ScrollingMovementMethod()); 
     tvConsole.setSelected(true); 

     handler.postDelayed(this, TIME_DELAY); 

     // Only display weather data while service is enabled 
     if (isServiceRunning()) { 
      GetWeather weather = new GetWeather(strPosition); 
      weather.returnWeather(); 

      // Weather package 
      tvConsole 
        .append("Weather Update\n-------------------\n\nCurrent Temp (C): " 
          + weather.strTemp 
          + "C\n" 
          + "Wind is out of the " 
          + weather.strWindDir 
          + " at " 
          + weather.strWindSpeed 
          + " MPH\n" 
          + "Visibility is " 
          + weather.strVisibility 
          + " miles\n\n"); 

      // Auto-scroll textview 
      // Does not function on Android 4.0+ 
      final Layout layout = tvConsole.getLayout(); 
      if (layout != null) { 
       int scrollDelta = layout.getLineBottom(tvConsole 
         .getLineCount() - 1) 
         - tvConsole.getScrollY() 
         - tvConsole.getHeight(); 
       if (scrollDelta > 0) 
        tvConsole.scrollBy(0, scrollDelta); 
      } 

     } 

    } 
}; 

正如我前面提到的,這個工程預期在薑餅和FroYo,但ICSJellyBean操作系統無法查看由GetWeather設置的變量。我認爲,我在某處讀到這與需要一個AsyncTask有關,但我無法解決它的正面或反面。

先感謝

+0

如果你可以把任何日誌請! –

+0

它看起來像你可能試圖從UI線程以外的東西更新UI? –

+0

@ChrisStratton是的。事實上,這個問題從未發生過。 – Sam

回答

1

嘗試使用異步任務就是這樣,

在您的主要活動,

public class GetWeather extends AsyncTask<Void, Integer, Void> { 



    public GetWeather(Activity activity) { 
     this.activity = activity; 


     context = activity; 
     dialog = new ProgressDialog(context); 


    } 

    /** progress dialog to show user that the backup is processing. */ 
    private ProgressDialog dialog; 
    /** application context. */ 
    private Activity activity; 
    private Context context; 



    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     super.onPreExecute(); 






    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     // TODO Auto-generated method stub 


     GetWeather weather = new GetWeather(strPosition); 
     weather.returnWeather(); 


     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 



        tvConsole 
       .append("Weather Update\n-------------------\n\nCurrent Temp (C): " 
         + weather.strTemp 
         + "C\n" 
         + "Wind is out of the " 
         + weather.strWindDir 
         + " at " 
         + weather.strWindSpeed 
         + " MPH\n" 
         + "Visibility is " 
         + weather.strVisibility 
         + " miles\n\n"); 

     // Auto-scroll textview 
     // Does not function on Android 4.0+ 
     final Layout layout = tvConsole.getLayout(); 
     if (layout != null) { 
      int scrollDelta = layout.getLineBottom(tvConsole 
        .getLineCount() - 1) 
        - tvConsole.getScrollY() 
        - tvConsole.getHeight(); 
      if (scrollDelta > 0) 
       tvConsole.scrollBy(0, scrollDelta); 
     } 




        } 



    } 

而且這樣稱呼它,

new GetWeather(Mainactivity.this).execute(); 
+0

謝謝你。今晚我會研究一下,看看我能否將它融入現有項目。 – Sam

+0

已經做了一些調整,但現在我得到了所有的工作。謝謝! – Sam

2

你不能碰任何東西在後臺線程的ui線程中,使用Handlers來初始化你的backgro和線程傳遞一個Handler對象。數據到達時使用處理程序向ui發送消息。在來自後臺線程的消息到來時,只需更新視圖即可。

相關問題