据我所知,我们无法从AsyncTask的doInBackground方法更改UI元素,但是在执行相同操作和更改TextView文本时没有任何异常。
public class MainActivity extends Activity {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
Toast.makeText(MainActivity.this, "Main : " + Thread.currentThread().getName(), Toast.LENGTH_SHORT).show();
new DemoAsync().execute();
}
class DemoAsync extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
String threadName = "Async : " + Thread.currentThread().getName();
for(int i=0;i<1000;i++) {
tv.setText("Changed " + i);
}
return threadName;
}
@Override
protected void onPostExecute(String threadName) {
Toast.makeText(MainActivity.this, threadName, Toast.LENGTH_SHORT).show();
}
}
}
我尝试检查doInBackground是否在主线程中运行,但事实并非如此。但是,在doInbackground中显示Toast时,应用程序会崩溃。修改TextView也应该使应用程序崩溃。有人可以解释这种行为吗?
PS - 关于可能的重复,我在前棒棒糖上运行代码,所以问题以及所选择的答案与此无关。此外,答案表明修改TextView将在以后的调用中崩溃(第18次到在选择的答案的情况下是准确的。)我已经更新了代码,以便在1000次迭代的循环中修改TextView,并且它仍然可以正常运行。答案 0 :(得分:0)
您不应按照Android "Processes and Threads" documentation:
中的说明从doInBackground
访问用户界面
不要从UI线程外部访问Android UI工具包
答案 1 :(得分:0)
这只是一个时间上的误解:乍一看似乎doInBackground()中的spinner = (Spinner) findViewById(R.id.spinner2);
List<String> list = new ArrayList<String>();
list.add("list 1");
list.add("list 2");
list.add("list 3");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.spinner_item, list);
spinner.setAdapter(dataAdapter);
改变了UI中的视图,
<强>但强>
实际上,当执行最后一个setText时,UI还没有准备好并与活动连接,因此循环中的最后一个setText会更改一个尚未在UI中的视图。
如果我们延迟循环,例如通过10000次迭代,UI将启动,我们将获得始终异常“只有创建层次结构视图的原始线程才能触及其视图”。
答案 2 :(得分:0)
我们可以使用下面的功能通过doinbackground来更新ui。
drwxr-xr-x - algo algo 0 2018-08-29 23:07 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/00
drwxr-xr-x - algo algo 0 2018-08-29 23:11 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/01
drwxr-xr-x - algo algo 0 2018-08-29 23:17 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/02
drwxr-xr-x - algo algo 0 2018-08-29 23:23 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/03
drwxr-xr-x - algo algo 0 2018-08-29 23:13 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/04
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/05
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/06
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/07
drwxr-xr-x - algo algo 0 2018-08-29 23:18 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/08
drwxr-xr-x - algo algo 0 2018-08-29 23:21 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/09
drwxr-xr-x - algo algo 0 2018-08-29 23:18 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/10
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/11
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/12
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/13
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/14
drwxr-xr-x - algo algo 0 2018-08-29 23:17 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/15
drwxr-xr-x - algo algo 0 2018-08-29 23:20 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/16
drwxr-xr-x - algo algo 0 2018-08-29 23:18 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/17
drwxr-xr-x - algo algo 0 2018-08-29 23:21 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/18
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/19
drwxr-xr-x - algo algo 0 2018-08-29 23:17 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/20
drwxr-xr-x - algo algo 0 2018-08-29 23:19 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/21
drwxr-xr-x - algo algo 0 2018-08-29 23:15 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/22
drwxr-xr-x - algo algo 0 2018-08-29 23:21 hdfs://n21-01-03/algo/ml_platform/downsample_data/nl/20180828/23
答案 3 :(得分:-2)
点击此处AsyncTask
AsyncTask可以正确,轻松地使用UI线程。此类允许执行后台操作并在UI线程上发布结果,而无需操作线程和/或处理程序。
编辑:在OOP中,您可以从内部类访问全局变量。所以,从这个角度来看,在这个例子中,扩展AsyncTask的类是内部类,你可以访问TextView tv;因为在主UI线程中调用execute,因此你可以修改但是如果它不是内部类,你就无法访问根据抽象定义的变量,因为doInBackground在另一个线程(而不是UI)中运行。简而言之,你不能修改doInBackground()中的UI元素,但是内部类可以访问全局声明的widget对象来更改容器中的值,就像在这个问题中所做的那样