2012-04-16 51 views
1

我正在爲Android做一個天氣應用程序,我正嘗試在runOnUiThread中使用我的線程中的非最終變量。但是,我不能這樣做。runOnUiThread中非最終變量的使用

我在做什麼錯?

下面是整個活動的代碼。線程正在從yr.no解析xml。

public class WeatherActivity extends Activity implements OnClickListener { 

ImageView forecastImage; 
TextView updateWeatherText; 
TextView temperatureText; 
TextView cloudinessText; 
TextView windspeedText; 
TextView precipitationText; 

Thread updateWeather = new Thread(new GetWeather()); 
Thread updateWeatherFromButton = new Thread(new GetWeather()); 

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

    forecastImage = (ImageView) findViewById(R.id.forecastIcon); 

    updateWeatherText = (TextView) findViewById(R.id.updatingWeatherText); 

    temperatureText = (TextView) findViewById(R.id.temperatureText); 
    cloudinessText = (TextView) findViewById(R.id.cloudinessText); 
    windspeedText = (TextView) findViewById(R.id.windspeedText); 
    precipitationText = (TextView) findViewById(R.id.precipitationText); 

    updateWeather.start(); 

    Button refreshButton = (Button) findViewById(R.id.refreshButton); 
    refreshButton.setOnClickListener(this); 
} 

class GetWeather implements Runnable { 

    public void run() { 

     try { 

      String temp; 
      String windspeed; 
      String cloudiness; 
      String precipitation; 


      URL weatherURL = new URL(
        "http://api.yr.no/weatherapi/locationforecast/1.8/?lat=62.39;lon=17.30"); 

      XmlPullParserFactory parserFactory = XmlPullParserFactory 
        .newInstance(); 
      XmlPullParser parser = parserFactory.newPullParser(); 

      parser.setInput(weatherURL.openStream(), null); 

      updateWeatherText.setText("Updating..."); 
      int parserEvent = parser.getEventType(); 
      while (parserEvent != XmlPullParser.END_DOCUMENT) { 

       switch (parserEvent) { 

       case XmlPullParser.TEXT: 
        String tag = parser.getName(); 

        if (tag.compareTo("temperature") == 0) { 
         temp = parser.getAttributeValue(
           null, "value") + " 'C"; 
        } else if (tag.compareTo("windSpeed") == 0) { 
         windspeed = parser.getAttributeValue(
           null, "mps") + " m/s"; 

        } else if (tag.compareTo("cloudiness") == 0) { 
         if (Integer.parseInt(parser.getAttributeValue(null, 
           "percent")) >= 0 
           && Integer 
             .parseInt(parser.getAttributeValue(
               null, "percent")) <= 12.5) { 
          cloudiness = "Klart"; 
         } else if (Integer.parseInt(parser 
           .getAttributeValue(null, "percent")) > 12.5 
           && Integer 
             .parseInt(parser.getAttributeValue(
               null, "percent")) < 25) { 
          cloudiness = "Mestadels klart"; 
         } else if (Integer.parseInt(parser 
           .getAttributeValue(null, "percent")) >= 25 
           && Integer 
             .parseInt(parser.getAttributeValue(
               null, "percent")) < 75) { 
          cloudiness = "Växlande molnighet"; 
         } else if (Integer.parseInt(parser 
           .getAttributeValue(null, "percent")) >= 75 
           && Integer 
             .parseInt(parser.getAttributeValue(
               null, "percent")) < 87.5) { 
          cloudiness = "Mestadels mulet"; 
         } else if (Integer.parseInt(parser 
           .getAttributeValue(null, "percent")) >= 87.5 
           && Integer 
             .parseInt(parser.getAttributeValue(
               null, "percent")) <= 100) { 
          cloudiness = "Mulet"; 
         } 

        } else if (tag.compareTo("precipitation") == 0) { 
         if (Integer.parseInt(parser.getAttributeValue(null, "minvalue")) > 0) forecastImage.setBackgroundResource(R.drawable.rain); 
         precipitation = "Mellan " 
             + parser.getAttributeValue(null, 
               "minvalue") 
             + " mm och " 
             + parser.getAttributeValue(null, 
               "maxvalue") + " mm"; 
        } 
        break; 
       } 
       parserEvent = parser.next(); 

       runOnUiThread(new Runnable() { 

        public void run() { 
         temperatureText.setText(temp); 
         windspeedText.setText(windspeed); 
         cloudinessText.setText(cloudiness); 
         precipitationText.setText(precipitation); 

         if (cloudiness.compareTo("Klart") == 0){ 
          forecastImage.setBackgroundResource(R.drawable.sunny); 
         } else if (cloudiness.compareTo("Mestadels klart") == 0) { 
          forecastImage.setBackgroundResource(R.drawable.sunny); 
         } 
          else if (cloudiness.compareTo("Växlande molnighet") == 0) { 
           forecastImage.setBackgroundResource(R.drawable.cloudy); 
         } else if (cloudiness.compareTo("Mestadels mulet") == 0) { 
          forecastImage.setBackgroundResource(R.drawable.overcast); 
         } else if (cloudiness.compareTo("Mulet") == 0) { 
          forecastImage.setBackgroundResource(R.drawable.overcast); 
         }       
        } 
       }); 
      } 
      updateWeatherText.setText("Last updated: " 
        + System.currentTimeMillis()); 

     } catch (Exception e) { 
     } 
    } 
} 

public void onClick(View v) { 

    switch (v.getId()) { 

    case R.id.refreshButton: 
     updateWeatherFromButton.start(); 

    } 
} 

回答

1

正如有些人已經指出你不能。一種解決方法是在定義Runnable之前將非最終變量重新分配給最終變量:

String aNonFinalString = "a"; 
aNonFinalString = "b"; 

final String aFinalString = aNonFinalString; 

runOnUiThread(new Runnable() { 
    public void run() { 
     useYourString(aFinalString); 
    } 
} 
+1

這是錯誤的。 aNonFinalString的值可能會隨着執行run方法而改變。這是爲什麼它應該是'最終'的原因。 – Anirudh 2012-04-16 20:10:47

+0

@Anirudh不知道我明白你的意思。我在runnable中不使用aNonFinalString,這就是整個問題。 – assylias 2012-04-16 20:18:15

+0

我試圖說開發者@ user1258829可能不會期待可能的'陳舊'值,即最終的String aFinalString = aNonFinalString;當runnable實際運行時。 aNonFinalString可能會根據某種邏輯進行更改。但runnable將只提供最終變量的值。 – Anirudh 2012-04-16 20:21:43