doInBackground无法在Android片段中运行

时间:2012-11-14 13:10:57

标签: android android-asynctask android-fragments

我有一个片段Fragment1.In该片段我正在解析XML并填充列表视图。我必须在fragment的背景中执行函数解析和列表视图的填充。因此它不会打扰用户。当我使用Asynctask时并且在doInBackground中定义了列表视图函数的数量,它显示了一个错误,例如“执行doinbackground()时发生错误”。我在这做错了什么?

这是我的片段

片段1 =>

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





        }

        }
}

这是我的错误日志,

11-14 18:29:42.705: E/AndroidRuntime(10530): java.lang.RuntimeException: An error occured while executing doInBackground()
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.os.AsyncTask$3.done(AsyncTask.java:278)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.lang.Thread.run(Thread.java:856)
11-14 18:29:42.705: E/AndroidRuntime(10530): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4056)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:2210)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:657)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.View.setFlags(View.java:6736)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.view.View.setFocusableInTouchMode(View.java:4714)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.widget.AdapterView.checkFocus(AdapterView.java:705)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.widget.GridView.setAdapter(GridView.java:186)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at com.madhyamam.malayalam2.Kerala.populate_listview(Kerala.java:149)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at com.madhyamam.malayalam2.Kerala$ProgressAsyncTask.doInBackground(Kerala.java:215)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at com.madhyamam.malayalam2.Kerala$ProgressAsyncTask.doInBackground(Kerala.java:1)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at android.os.AsyncTask$2.call(AsyncTask.java:264)
11-14 18:29:42.705: E/AndroidRuntime(10530):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

3 个答案:

答案 0 :(得分:2)

您正在对异步线程中的ui进行更改。将您将新适配器设置的最后3行移动到populate_listview()方法到onPostExecute()的列表中。此方法在您的ui线程上执行,可以更改您的ui。

答案 1 :(得分:1)

populate_listview();的{​​{1}}中致电onPostExecute() ..

日志显示

  

引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。

无法直接跨线程更新UI。

答案 2 :(得分:1)

使用AsyncTask的想法是执行后台进程,但在后台进程中不会访问/修改当前UI的任何元素。这是一个不同的主题。如果您正在尝试更新/编辑当前活动/片段/ UI的列表(例如:ListView /自定义LinearLayout实现,如列表视图),那么您可以考虑在后台进程中生成列表[可能是Plain Old Java Objects( POJO)或者可能是视图 - 新实例/膨胀]并且作为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();
}