Android 必须从UI线程调用方法setText
在stackoverflow上读取所有集合并从UI线程调用,但似乎没有一个是相关的。这段代码在20年前就开始工作了,最近才打开。它显示了这个错误。“必须从UI线程调用方法setText”。Android 必须从UI线程调用方法setText,android,multithreading,android-asynctask,background,Android,Multithreading,Android Asynctask,Background,在stackoverflow上读取所有集合并从UI线程调用,但似乎没有一个是相关的。这段代码在20年前就开始工作了,最近才打开。它显示了这个错误。“必须从UI线程调用方法setText”。 什么更新正在做这件事? 用注释标记setText行以使其更清晰。有什么建议吗 public class MainActivity extends Activity { static final String baseURL = "http://api.yr.no/weatherapi/locatio
什么更新正在做这件事? 用注释标记setText行以使其更清晰。有什么建议吗
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);
}
}
}
});
}
}
公共类MainActivity扩展活动{
静态最终字符串baseURL=”http://api.yr.no/weatherapi/locationforecast/1.9/?lat=";
TextView dato、平地机、vindhastighet、vindretning;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build();StrictMode.setThreadPolicy(策略);
SmartLocation.with(this.location())
.oneFix()
.start(新的OnLocationUpdatedListener(){
@凌驾
已更新公共void onLocation(位置){
dato=(TextView)findViewById(R.id.gpsbydato_txt);
分级器=(文本视图)findViewById(R.id.gpsbygrader_txt);
vindhastighet=(TextView)findViewById(R.id.gpsbyvindhistighet_txt);
葡萄酒酿造=(TextView)findViewById(R.id.gpsbyvindretning_txt);
双纬度=location.getLatitude();
Double longtudent=location.getLongitude();
StringBuilder Url=新的StringBuilder(baseURL);
Url.append(纬度+“lon=”长度);
最后一个字符串fullUrl=Url.toString();
类读取扩展异步任务{
@凌驾
受保护的字符串doInBackground(字符串…arg0){
试一试{
URL网站=新URL(完整URL);
//xmlreader解析器数据
SAXParserFactory spf=SAXParserFactory.newInstance();
SAXParser sp=spf.newSAXParser();
XMLReader xr=sp.getXMLReader();
HandlingXMLStuff doingWork=新HandlingXMLStuff();
xr.setContentHandler(doingWork);
xr.parse(新输入源(website.openStream());
字符串informationTemp=doingWork.getInformationTemp();
String informationVindretning=doingWork.getInformationVindretning();
字符串informationVindhastighet=doingWork.getInformationVindhastighet();
//grader.setText导致错误。
平地机设置文本(信息温度);
//vindhastighet.setText导致错误。
setText(informationVindhastighet);
//vindretning.setText导致了错误。
setText(informationVindretning);
}捕获(例外e){
Log.e(“URL:,fullUrl”);
dato.setText(“erroorr”);//也是这个setText
系统输出打印ln(e);
}
返回null;
}
@凌驾
受保护的void onPostExecute(字符串结果){
dato.setText(结果);
super.onPostExecute(结果);
}
}
}
});
}
}
这实际上是在关闭严格模式,它允许不安全的事情,比如在非UI线程上更新UI,而不是将其记录到磁盘上。这实际上是不允许的。所以你的代码总是错误的,你只是忽略了错误,希望你不会被抓住。正确的修复方法是将代码移动到UI线程,并可能在整个代码库中删除对StrictMode的所有提及-它应该仅用作调试工具,甚至可能不作为调试工具使用 所有关于不从线程更新UI的建议都是绝对相关的——您在doInBackground中的一个异步任务上设置UI——所以从另一个线程。通过runOnUiThread、处理程序或推迟到onPostExecute或进度消息,将其移动到UI线程
这实际上是在关闭严格模式,它允许不安全的事情,比如在非UI线程上更新UI,而不是将其记录到磁盘上。这实际上是不允许的。所以你的代码总是错误的,你只是忽略了错误,希望你不会被抓住。正确的修复方法是将代码移动到UI线程,并可能在整个代码库中删除对StrictMode的所有提及-它应该仅用作调试工具,甚至可能不作为调试工具使用
所有关于不从线程更新UI的建议都是绝对相关的——您在doInBackground中的一个异步任务上设置UI——所以从另一个线程。通过runOnUiThread、处理程序或推迟到onPostExecute或进度消息,将其移动到UI线程。您不能从
异步任务中的doInBackground
更新UI
所有与UI相关的操作都需要在UI线程内完成
您可以使用runonUithread
在doInBackground
这是一个
代码:
或者..更好的解决方案是将setText()
代码移到onPostExecute()中
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .detectAll().penaltyLog().build(); StrictMode.setThreadPolicy(policy);
@Override
protected String doInBackground(String... arg0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
grader.setText(informationTemp);
vindhastighet.setText(informationVindhastighet);
vindretning.setText(informationVindretning);
}
});
}
@Override
protected String doInBackground(String... arg0) {
...........
...................
runOnUiThread(new Runnable() {
@Override
public void run() {
grader.setText(informationTemp);
vindhastighet.setText(informationVindhastighet);
vindretning.setText(informationVindretning);
}
});
.............
.....................
}