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();
}
}
잘못된 방법입니다. aNonFinalString의 값은 run 메서드가 실행될 때까지 변경 될 수 있습니다. 그것이 '최종'이어야하는 이유가 있습니다. – Anirudh
@Anirudh 무슨 뜻인지 잘 모르겠다. 나는 runnable에서 aNonFinalString을 사용하지 않는다. – assylias
개발자 @ user1258829가 '부실'값 (예 : final String aFinalString = aNonFinalString)을 기대하지 않는다고 말하려고했습니다. 실행 파일이 실제로 실행될 때. aNonFinalString은 일부 논리에 따라 변경 될 수 있습니다. 그러나 runnable은 최종 값으로 스냅 샷을 제공합니다. – Anirudh