我在尝试显示加载消息时发现此消息,或者您可以在我的活动中说明进度条。
我尝试在UI线程和AsyncTask中使用Thread.currentThread.getId()
打印线程ID。两者都打印1。
如果两者都在同一个线程上运行,那么我们如何在运行复杂任务时更改UI(建议在onPreExecute
中执行)(建议在doInBackground
中执行)。
请解释
答案 0 :(得分:1)
doInBackground()
在后台线程上运行,然后才会正确使用AsyncTask
。
doInBackground()
无法直接更改UI,因为它在后台线程上运行。如果您在doInBackground()
运行时需要进行更改,请致电publishProgress()
。这会触发对onProgressUpdate()
的调用,并且将在主应用程序线程上调用。
例如,这个保留的片段有一个AsyncTask
,可以通过ListView
向ArrayAdapter
添加单词,因为单词可用(使用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)
答案 1 :(得分:0)
AsyncTask
执行命令在Main UiThread
上运行但doInBackground
在worker thread
上运行,这意味着Thread.currentThread.getId()
中的doInBackground()
将返回不同的号码
希望这会有所帮助。
答案 2 :(得分:0)
在幕后,Async Task实际上使用HaMeR框架在doInBackground()
中创建了一个新线程。所以它真的取决于你在哪里打印线程ID。