读取了所有的set并从UI线程调用,在stackoverflow上但似乎没有相关的。这段代码工作了2年,最近打开了它。它显示了这个错误。 “必须从UI线程调用方法setText” 有什么更新呢? 用注释标记setText行以使其更清晰。任何sugestions?
public class MainActivity extends Activity {
static final String baseURL = "http://api.yr.no/weatherapi/locationforecast/1.9/?lat=";
TextView dato, grader, vindhastighet, vindretning;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .detectAll().penaltyLog().build(); StrictMode.setThreadPolicy(policy);
SmartLocation.with(this).location()
.oneFix()
.start(new OnLocationUpdatedListener() {
@Override
public void onLocationUpdated(Location location) {
dato = (TextView)findViewById(R.id.gpsbydato_txt);
grader = (TextView)findViewById(R.id.gpsbygrader_txt);
vindhastighet = (TextView)findViewById(R.id.gpsbyvindhastighet_txt);
vindretning = (TextView)findViewById(R.id.gpsbyvindretning_txt);
Double latitude = location.getLatitude();
Double longtitude = location.getLongitude();
StringBuilder Url = new StringBuilder(baseURL);
Url.append(latitude + ";lon=" + longtitude);
final String fullUrl = Url.toString();
class Read extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... arg0) {
try {
URL website = new URL(fullUrl);
//xmlreader parser data
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
HandlingXMLStuff doingWork = new HandlingXMLStuff();
xr.setContentHandler(doingWork);
xr.parse(new InputSource(website.openStream()));
String informationTemp = doingWork.getInformationTemp();
String informationVindretning = doingWork.getInformationVindretning();
String informationVindhastighet = doingWork.getInformationVindhastighet();
//grader.setText is causing the error.
grader.setText(informationTemp);
//vindhastighet.setText is causing the error.
vindhastighet.setText(informationVindhastighet);
//vindretning.setText is causing the error.
vindretning.setText(informationVindretning);
} catch (Exception e) {
Log.e("URL:", fullUrl);
dato.setText("erroorrr"); //also this setText
System.out.println(e);
}
return null;
}
@Override
protected void onPostExecute(String result) {
dato.setText(result);
super.onPostExecute(result);
}
}
}
});
}
}
答案 0 :(得分:4)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .detectAll().penaltyLog().build(); StrictMode.setThreadPolicy(policy);
这实际上是关闭严格模式,这允许不安全的事情,例如更新非UI线程上的UI而不是将其记录到磁盘。实际上不允许这样做了。所以你的代码总是错的,你只是忽略了错误,并希望你不会被抓住。正确的解决方法是将代码移动到UI线程,并且可能在整个代码库中删除StrictMode的所有提及 - 它应该只用作调试工具,甚至可能不会用。
关于不从线程更新UI的所有建议都是绝对相关的 - 你在doInBackground中的AsyncTask上设置UI,所以从另一个线程。通过runOnUiThread,处理程序或将其关闭直到onPostExecute或进度消息,将其移动到UI线程。
答案 1 :(得分:2)
您无法从doInBackground
中的AsyncTask
更新用户界面。
所有与UI相关的操作都需要在UI线程内完成。
您可以使用runonUithread
更新doInBackground
这是example
代码:
@Override
protected String doInBackground(String... arg0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
grader.setText(informationTemp);
vindhastighet.setText(informationVindhastighet);
vindretning.setText(informationVindretning);
}
});
}
或者......更好的解决方案是将setText()
代码移到onPostExecute()