我在尝试显示加载消息时发现了这个,或者你可以在我的 Activity 上说一个进度条。
我尝试在 UI 线程和 AsyncTask 中使用 Thread.currentThread.getId()
打印线程 ID。两者都打印 1。
如果两者都在同一个线程上运行,那么我们如何在运行复杂任务(建议在doInBackground
中执行)的同时更改 UI(建议在 onPreExecute
中执行)。
请解释
最佳答案
doInBackground()
在后台线程上运行,然后仅当您正确使用 AsyncTask
时。
doInBackground()
无法直接更改 UI,因为它在后台线程上运行。如果您需要在 doInBackground()
运行时进行更改,请调用 publishProgress()
。这会触发对 onProgressUpdate()
的调用,并将在主应用程序线程上调用。
例如,这个保留的 fragment 有一个 AsyncTask
,它会在单词可用时通过它的 ArrayAdapter
将单词添加到 ListView
(使用 Thread.sleep()
模拟网络 I/O 的延迟):
/***
Copyright (c) 2008-2014 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
From _The Busy Coder's Guide to Android Development_
https://commonsware.com/Android
*/
package com.commonsware.android.async;
import android.app.ListFragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;
public class AsyncDemoFragment extends ListFragment {
private static final String[] items= { "lorem", "ipsum", "dolor",
"sit", "amet", "consectetuer", "adipiscing", "elit", "morbi",
"vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam",
"vel", "erat", "placerat", "ante", "porttitor", "sodales",
"pellentesque", "augue", "purus" };
private ArrayList<String> model=new ArrayList<String>();
private ArrayAdapter<String> adapter=null;
private AddStringTask task=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
task=new AddStringTask();
task.execute();
adapter=
new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1,
model);
}
@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
getListView().setScrollbarFadingEnabled(false);
setListAdapter(adapter);
}
@Override
public void onDestroy() {
if (task != null) {
task.cancel(false);
}
super.onDestroy();
}
class AddStringTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... unused) {
for (String item : items) {
if (isCancelled())
break;
publishProgress(item);
SystemClock.sleep(400);
}
return(null);
}
@Override
protected void onProgressUpdate(String... item) {
if (!isCancelled()) {
adapter.add(item[0]);
}
}
@Override
protected void onPostExecute(Void unused) {
Toast.makeText(getActivity(), R.string.done, Toast.LENGTH_SHORT)
.show();
task=null;
}
}
}
(来自 this sample project 在 this book 中描述)
关于java - Main UI 和 AsyncTask 是否在同一个线程上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34990553/