2012-04-16 2 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

+0

@Anirudh 무슨 뜻인지 잘 모르겠다. 나는 runnable에서 aNonFinalString을 사용하지 않는다. – assylias

+0

개발자 @ user1258829가 '부실'값 (예 : final String aFinalString = aNonFinalString)을 기대하지 않는다고 말하려고했습니다. 실행 파일이 실제로 실행될 때. aNonFinalString은 일부 논리에 따라 변경 될 수 있습니다. 그러나 runnable은 최종 값으로 스냅 샷을 제공합니다. – Anirudh