doInBackground在Android片段中不起作用
我有一个片段Fragment1。在该片段中,我正在解析XML并填充列表视图。我必须在片段的后台执行函数解析和填充列表视图。这样它就不会干扰用户。当我在doInBackground中使用Asynctask并定义填充列表视图函数时,它显示了一个类似于发生错误的错误在执行doinbackground时。我做错了什么 这是我的片段 片段1=>doInBackground在Android片段中不起作用,android,android-asynctask,android-fragments,Android,Android Asynctask,Android Fragments,我有一个片段Fragment1。在该片段中,我正在解析XML并填充列表视图。我必须在片段的后台执行函数解析和填充列表视图。这样它就不会干扰用户。当我在doInBackground中使用Asynctask并定义填充列表视图函数时,它显示了一个类似于发生错误的错误在执行doinbackground时。我做错了什么 这是我的片段 片段1=> public class Kerala extends Fragment{ static String URL = ""; // XML node keys
public class Kerala extends Fragment{
static String URL = "";
// XML node keys
static final String KEY_HEAD = "item"; // parent node
//static final String KEY_TITLE = "title";
static final String KEY_DATE = "pubDate";
public static String headflag="";
int f=0;
GridView list;
KeralaAdapter adapter;
public static String[] Title;
public static String[] Description;
public static String[] Tit;
public static String[] Tit2;
public static String[] Desc;
public static String[] Desc2;
public static String[] image;
public static String[] Date;
public static String[] Flash;
public static String[] Fl;
public static String[] Fl2;
private TextView mMessageView;
private Button mClearButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating layout
View v = inflater.inflate(R.layout.kerala_fragment, container, false);
// We obtain layout references
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
new ProgressAsyncTask().execute();
}
public void populate_listview()
{
URL="http://www.abcd.com/en/rssfeeds/9/latest/rss.xml";
ArrayList<HashMap<String, String>> newsList = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML from URL
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_HEAD);
// looping through all song nodes <song>
NodeList itemLst = doc.getElementsByTagName("item");
String MarqueeStr="";
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
//map.put(KEY_DATE, parser.getValue(e, KEY_DATE));
newsList.add(map);
}
list=(GridView)getActivity().findViewById(R.id.grid2);
// Getting adapter by passing xml data ArrayList
adapter=new KeralaAdapter(getActivity(), newsList);
list.setAdapter(adapter);
}
public void StartProgress(){
new ProgressAsyncTask().execute();
}
public class ProgressAsyncTask extends
AsyncTask<Void, Integer, Void> {
int myProgress;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
myProgress = 0;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
keralaparser.parse();//here I am calling both functions
populate_listview();
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
}
}
}
调用列表视图;在异步任务的onPostExecute中
日志显示
原因:android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图
无法跨线程直接更新UI。您正在异步线程中更改UI。将最后3行作为新适配器的位置从populate_listview方法移动到onPostExecute。此方法在ui线程上执行,可以更改ui。使用AsyncTask的想法是执行后台进程,但在后台进程中不会访问/修改当前ui的任何元素。这是另一条线。如果您试图更新/编辑EXCELVIEW/Sudio线性布局的列表,如当前活动/片段/UI的列表视图,则可以考虑在后台进程中生成列表(可以是普通的java对象POJOS或可以是视图-新实例/充气)并将其作为doInBackground方法的结果返回:
@Override
protected View doInBackground(Void... params) {
return generateListResults();
}
在此之后,您现在可以访问/修改当前活动/片段/UI。这可能在onPostExecute方法内部,将结果作为参数传递,如下所示,[遵循doInBackground方法]:
@Override
protected void onPostExecute(View result) {
resultContainer.addView(result);
dialog.dismiss();
super.onPostExecute(result);
}
在启动后台进程之前,您可以选择显示加载对话框:
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(context, res.getString(R.string.searching), res.getString(R.string.wait), true);
resultContainer.removeAllViews();
super.onPreExecute();
}
在onPostExecute中调用populate_listview方法将使AsyncTask完全无用。@Luksprog否。他在调用populate_listview之前在doInBackground中进行了一些分析。。
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(context, res.getString(R.string.searching), res.getString(R.string.wait), true);
resultContainer.removeAllViews();
super.onPreExecute();
}