Android asynctask,防止UI冻结

时间:2014-03-23 19:08:46

标签: android xml android-listview android-asynctask

我有这种代码的安静,从网址中获取一些xml数据。

它的工作正常,但问题是它下载时 并解析xml UI冻结,这可能是用户的问题。

这是班级

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.kategoria);

    // getting intent data
    Intent in = getIntent();
    String cat_name = in.getStringExtra("kategoria");
    //Update Textview
    TextView kategoriatw = (TextView)findViewById(R.id.name_of_cat);
    kategoriatw.setText(cat_name);



    // Kategoro URL
    String catUrl = "http://sample.com/xmldata.xml";


    ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
    //MOTHERLAJME MULTIDIMENSIONAl
    final List<HashMap<String, String>> MotherContainer= new ArrayList<HashMap<String, String>>();


    try{ 

        XMLParser parser = new XMLParser();
        String xml   = parser.getXmlFromUrl(catUrl); // getting XML
        Document doc = parser.getDomElement(xml); // getting DOM element


        //ALL
        NodeList forecastW = doc.getElementsByTagName("newsitem");

        for (int j = 0; j < forecastW.getLength(); j++)
        {
            HashMap<String, String> map = new HashMap<String, String>();

            Node nodeday = forecastW.item(j);
            Element dayElmnt = (Element) nodeday;

            map.put("title", (parser.getValue(dayElmnt, "title")) );
            map.put("intro", (parser.getValue(dayElmnt, "intro")).toString());

            map.put("story_id", ""+j ); 

            // adding HashList to ArrayList
            menuItems.add(map);


            //MULTI DIMENSIONAL ARRAY
            HashMap<String, String> TheStory= new HashMap<String, String>();
            TheStory .put("title", (parser.getValue(dayElmnt, "title")));
            TheStory .put("story_date", parser.getValue(dayElmnt, "datetime"));
            MotherContainer.add(j, TheStory);
            /////////////////////////

        }


    } catch (Exception e) {
        System.out.println("XML Pasing Excpetion = " + e);
    }



    // Adding menuItems to ListView
    ListAdapter adapter = new SimpleAdapter(this, menuItems,
            R.layout.week_day_item,
            new String[] { "title", "intro", "story_id"}, new int[] {
                    R.id.title_list,
                    R.id.intro_list,
                    R.id.story_id_list});

    setListAdapter(adapter);

    // selecting single ListView item
    ListView lv = getListView();


    lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

            // Starting new intent
            Intent in = new Intent(getApplicationContext(), SingleLajm.class);
            //start new intent....
            startActivity(in);

        }

    });

}

我想使用Asynctask,以便UI不会冻结,我在我的课上使用它, 这是我使用的类的“更新”版本,它实现了异步:

Document doc;
String xml;
ListView lv;
//ListViewAdapter adapter;
//ArrayList<HashMap<String, String>> menuItems;
ProgressDialog pDialog;


final ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
//MOTHERLAJME MULTIDIMENSIONAl
final List<HashMap<String, String>> MotherLajme= new ArrayList<HashMap<String, String>>();

final HashMap<String, String> nrLajmit = new HashMap<String, String>();


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.kategoria);

    // getting intent data
    Intent in = getIntent();
    // Get emr
    String catname = in.getStringExtra("kategoria");
    //Textview
    TextView kategoriatw = (TextView)findViewById(R.id.kategoria_emri);
    kategoriatw.setText(catname);



}

private class loadMoreListView extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        // Showing progress dialog before sending http request
        pDialog = new ProgressDialog(
                Kategoria.this);
        pDialog.setMessage("Please wait..");
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    protected Void doInBackground(Void... unused) {
        new Runnable() {
            public void run() {


                XMLParser parser = new XMLParser();
                String xml   = parser.getXmlFromUrl("http://sample.com/data.xml"); // getting XML
                Document doc = parser.getDomElement(xml); // getting DOM element


                //ALL
                NodeList forecastW = doc.getElementsByTagName("newsitem");

                for (int j = 0; j < forecastW.getLength(); j++)
                {
                    HashMap<String, String> map = new HashMap<String, String>();

                    Node nodeday = forecastW.item(j);
                    Element dayElmnt = (Element) nodeday;

                    map.put("title", (parser.getValue(dayElmnt, "title")) );
                    map.put("intro", (parser.getValue(dayElmnt, "intro")) );

                    map.put("story_id", ""+j ); 
                    // adding HashList to ArrayList
                    menuItems.add(map);


                    //MULTI DIMENSIONAL ARRAY
                    HashMap<String, String> TheLajmi= new HashMap<String, String>();
                    TheLajmi .put("title", (parser.getValue(dayElmnt, "title")));
                    TheLajmi .put("newsdate", parser.getValue(dayElmnt, "datetime"));
                    MotherLajme.add(j, TheLajmi);
                    /////////////////////////

                }


            }
        };

        return (null);
    }


    protected void onPostExecute(Void unused) {
        // closing progress dialog
        pDialog.dismiss();

        // Adding menuItems to ListView
        ListAdapter adapter = new SimpleAdapter(Kategoria.this, menuItems,
                R.layout.week_day_item,
                new String[] { "title", "intro", "story_id"}, new int[] {
                        R.id.title_list,
                        R.id.intro_list,
                        R.id.story_id_list});

        setListAdapter(adapter);

        // selecting single ListView item
        ListView lv = getListView();

        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // getting values from selected ListItem

                // Starting new intent
                Intent in = new Intent(getApplicationContext(), SingleLajm.class);
                in.putExtra("title", "blabla");
                startActivity(in);

            }

        });

    }
}

但我无法让它发挥作用。我看到的只是一个空白页面或一些错误 我无法编辑视图。

有人可以帮忙解决这个问题吗?

感谢。

1 个答案:

答案 0 :(得分:5)

尝试以下代码:

private class LoadMoreListView extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {

@Override
protected void onPreExecute() {
    // Showing progress dialog before sending http request
    pDialog = new ProgressDialog(
            AndroidListViewWithLoadMoreButtonActivity.this);
    pDialog.setMessage("Please wait..");
    pDialog.setIndeterminate(true);
    pDialog.setCancelable(false);
    pDialog.show();
}

protected ArrayList<HashMap<String, String>> doInBackground(Void... unused) {

      ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
//MOTHERLAJME MULTIDIMENSIONAl
final List<HashMap<String, String>> MotherContainer= new ArrayList<HashMap<String, String>>();


try{ 

    XMLParser parser = new XMLParser();
    String xml   = parser.getXmlFromUrl(catUrl); // getting XML
    Document doc = parser.getDomElement(xml); // getting DOM element


    //ALL
    NodeList forecastW = doc.getElementsByTagName("newsitem");

    for (int j = 0; j < forecastW.getLength(); j++)
    {
        HashMap<String, String> map = new HashMap<String, String>();

        Node nodeday = forecastW.item(j);
        Element dayElmnt = (Element) nodeday;

        map.put("title", (parser.getValue(dayElmnt, "title")) );
        map.put("intro", (parser.getValue(dayElmnt, "intro")).toString());

        map.put("story_id", ""+j ); 

        // adding HashList to ArrayList
        menuItems.add(map);


        //MULTI DIMENSIONAL ARRAY
        HashMap<String, String> TheStory= new HashMap<String, String>();
        TheStory .put("title", (parser.getValue(dayElmnt, "title")));
        TheStory .put("story_date", parser.getValue(dayElmnt, "datetime"));
        MotherContainer.add(j, TheStory);
        /////////////////////////

    }


} catch (Exception e) {
    System.out.println("XML Pasing Excpetion = " + e);
}


    return menuItems;
}


protected void onPostExecute(ArrayList<HashMap<String, String>> unused) {
    // closing progress dialog
    pDialog.dismiss();


     // Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(YourActivity.this, unused,
        R.layout.week_day_item,
        new String[] { "title", "intro", "story_id"}, new int[] {
                R.id.title_list,
                R.id.intro_list,
                R.id.story_id_list});

setListAdapter(adapter);


}

AsyncTask

第一个参数表示您可以传递以执行的类型。虚空意味着你什么都不能传递

Java中的类名应该以upper-calse字母开头。请重命名,以便其他人更好地阅读。

正确的呼叫将是

new LoadMoreListView().execute();

第二个参数是您可以发布从publishProgress()调用doInBackground()的一种数据。你没有使用publishProgress,所以在这种情况下没有什么可说的。

第三个参数将传递给onPostExecute()。要将menuItem传递给onPostExecute,必须从doInBackground返回它。所以你需要用

声明你的课程
AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>

doInBackground在新主题上运行,因此您不需要以下代码:

new Runnable() {
            public void run()

如果您想使用UI线程,可以使用以下方法:

  1. onPreExecute

  2. onPostExecute

  3. onPreExecute通常用于显示请等待对话或类似的内容以及onPostExecute用于在下载后显示数据和其他内容