当我阅读关于asyntask
的文档时,他们说:“不应该”更新doInbackground中的UI线程,因为doInbackground在不同的线程上工作。
这意味着:此操作会很危险,因为UI线程不是线程安全的。我明白了。但是当我尝试测试当我在此函数中更新UI线程时会发生什么。我收到错误:(但错误看起来并不像aysnchonize
,但因为我们不能这样做)
(TextView)((Activity)context).findViewById(R.id.text)).setText("StackOverFlow");
//context: reference of context object of UI Thread
请为我解释。我们是shouldn't
还是mustn't
。
谢谢:)
答案 0 :(得分:8)
我们无法从后台线程更新UI线程。 可能是他们阻止我们从后台线程更新UI的情况。
原因很明显...... @操作系统级别会有这么多线程将会运行。
还有 来自不同应用程序的不同线程,在这种情况下,如果我们可以从bg-thread更新UI,它将在屏幕上出现混乱
答案 1 :(得分:2)
在doInBackground内部,您将无法获得UI访问权限。如果您想从doInBackground获取UI访问权限,那么您将从那里进入onProgressUpdate,在UI上显示您想要显示的内容。
以下是您将检查的代码供您参考:
类DownloadAsyncTask扩展了AsyncTask {
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(Login.this, "", "Please Wait ...");
}
@Override
protected Void doInBackground(String... arg0) {
int status1 = validationuser(username);
Log.i("MyLog", "Inside the doInBackground is came"+status1);
if(status1 == 1)
{
publishProgress(status1+ "Valid User Code","1",""+status1);
}
else
{
publishProgress(status1+ " Invalid Valid User Code","0",""+status1);
}
return null;
}
@Override
protected void onProgressUpdate(String...values){
super.onProgressUpdate(values);
int index = Integer.parseInt(values[2]);
if(index == 1)
{
USERIDLOGIN = edittextuserName.getText().toString();
Intent intent=new Intent(Login.this, CollectionModuleandDownload.class);
/*Toast.makeText(Login.this, "Valid User Password", Toast.LENGTH_SHORT).show();*/
startActivity(intent);
progressDialog.dismiss();
}
else
{
Toast.makeText(Login.this, "Invalid Username & Password", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
@Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
/*if(progressDialog != null)
{
progressDialog.dismiss();
}*/
}
}
答案 2 :(得分:1)
所以你必须只在OnPostExecute&上更新ui。 OnPreExecute。 这是asynctask的一个很好的例子。试一试
你通过
来称呼它new SaveProfile().execute();
然后这......
private class SaveProfile extends AsyncTask<String, Void, Boolean>{
@Override
protected Boolean doInBackground(String... params) {
//---------- so your stuff here.... non ui related
Log.v("response from saving",response);
if(response.equals("1")){
return true;
}else{
return false;
}
}
protected void onPostExecute(Boolean result) {
if(result) {
//------ UPDATE UI HERE
Toast.makeText(ProfileCompanyActivity.this, "profile saved", 2500).show();
}else{
Toast.makeText(ProfileCompanyActivity.this, "an error occured", 2500).show();
}
}
}
答案 3 :(得分:1)
创建Aysnc
任务时,doInBackground
方法在UI线程的单独线程中运行。因此,您无法从此方法更新UI。
OnPostExecute
和onPreExecute
方法在与UI线程相同的线程中执行。如需进一步阅读,请转到here
答案 4 :(得分:0)
如果只允许一个线程触及用户界面,Android可以保证在测量视图并将其渲染到屏幕时不会发生任何重要变化 这是因为..用户界面只能在mainthread上更新。所有屏幕中的用户界面对象都由此主线程维护....现在,如果您尝试从其他线程更改用户界面(在后台执行)在这种情况下..它会导致错误,因为..例如..如果你试图从主线程以外更改搜索栏(某个小部件)值...并且用户试图放置不同的值...那么它是对于android来说是暧昧的...至于它应该听哪个线程...希望它澄清你的怀疑......
所以,就像我们不应该尝试......并且因为它的安全性......我们也不能尝试..因为它给出了错误.. =]
答案 5 :(得分:0)
doInBackground用于执行繁重的计算或您要在活动中执行的任何后台工作。 当你的doinbackground方法中的操作完成后,on postexecute方法会更新你的ui .. 简而言之,doinbackground不用于更新ui。
答案 6 :(得分:0)
我认为答案是我们不能
这对我来说似乎不合逻辑.. 它就像试图改变另一辆在你旁边的汽车的广播电台.. 这种架构不会那样工作..你可以在出发前往公路旅行或停止驾驶时决定一个广播电台,理论上你可以向他大喊并要求他改变电台,但你不能这样做自己。
答案 7 :(得分:0)
由于doInBackground()在单独的线程上运行,并且onPostExecute在UIMain线程上运行,并且根据Android提供的约束,您无法从其他线程更新UIMain线程。
由于上述原因,您在运行应用程序时会收到提及的消息。