Android异步任务下载XML

时间:2013-12-29 13:45:21

标签: android multithreading android-asynctask

美好的一天

我有应用程序whitch下载XML并在小部件上显示温度。当我按下小部件上的“更新按钮”并且我调用Load()方法时它工作得很好但是另一个Android手机需要在另一个线程中下载XML。我尝试使用异步任务,并在doInBackground()中调用Load()。我不知道故障在哪里。

我的负载()

public List<Contact> Load()
{
    final String URL = "http://192.168.1.110/index.xml";
    // XML node keys
    final String KEY_SONG = "data"; // parent node
    final String KEY_KEY = "id";
    final String KEY_NAME = "temperature";
    final String KEY_TEMPERATURE = "humidity";
    final String KEY_LATITUDE = "latitude";
    final String KEY_STATUS = "status";
    Databaze db = new Databaze(this);
    List<Contact> contacts;

    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_SONG);
    // looping through all mista nodes <mista>
    for (int j = 0; j < nl.getLength(); j++)
    {
        Element e = (Element) nl.item(j);

        String name = parser.getValue(e, KEY_NAME);
        String temperature = parser.getValue(e, KEY_TEMPERATURE);
        String latitude = parser.getValue(e, KEY_LATITUDE);
        String status = parser.getValue(e, KEY_STATUS);
        String key = parser.getValue(e, KEY_KEY);
        int keyINT = Integer.valueOf(key);

            if(keyINT == 1){
            db.updateContact(new Contact(keyINT, name, temperature, latitude, status));

            }
            else{
    db.addContact(new Contact(keyINT, name, temperature, latitude, status));
            }
    }
    contacts = db.getAllContacts();

    return contacts;
}

和异步任务

    public class LoadDataTask extends AsyncTask<Void, Void, List<Contact>>
{
//  private ProgressDialog dialog;
  //  private Databaze db;
  //  private  List<Contact> contacts;

    @Override
    protected void onPreExecute()
    {
        //super.onPreExecute();

    }
            @Override
    protected List<Contact> doInBackground(Void... voids)
    {

        MainActivity mainActivity = new MainActivity();


        return mainActivity.Load();

    }

    @Override
    protected void onPostExecute(List<Contact> cont)
    {
    //  super.onPostExecute(contacts);
        contacts = cont;


        contacts = db.getAllContacts();      

    }
}

getTemperature()此方法显示windget上的实际温度。

    private String getTemperature(Context context) {

       LoadDataTask task = new LoadDataTask(); 
        task.execute();

    String temperature = "-";
    db = new Databaze(context);
    contacts = db.getAllContacts();      

        for (Contact cn : contacts) {  
            temperature = cn.getName() + " °C";
            System.out.println(cn.getName()+ " °C++++");
        }           
    return temperature;
}

当我使用它时。它不起作用

LoadDataTask task = new LoadDataTask(); 
        task.execute();

但是当我在getTemperature中调用Load()时它运行良好。

错误代码:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.app.Activity.<init>(Activity.java:680)
at com.example.hello.MainActivity.<init>(MainActivity.java:26)
at com.example.hello.MyWidgetIntentReceiver$LoadDataTask.doInBackground(MyWidgetIntentReceiver.java:161)
at com.example.hello.MyWidgetIntentReceiver$LoadDataTask.doInBackground(MyWidgetIntentReceiver.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
... 4 more

我在项目的MainActivity类中使用此代码来加载XML数据。这有效。但asynctask上面的另一个类不起作用。

  public class LoadDataTask extends AsyncTask<Void, Void, List<Contact>>
{
    private ProgressDialog dialog;

    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        dialog = new ProgressDialog(MainActivity.this);
        dialog.setIndeterminate(true);
        dialog.setMessage("Loading");
        dialog.show();
    }

    @Override
    protected List<Contact> doInBackground(Void... voids)
    {
        return Load();
    }

    @Override
    protected void onPostExecute(List<Contact> cont)
    {
        super.onPostExecute(contacts);
        contacts = cont;
        dialog.dismiss();
        Toast.makeText(MainActivity.this, "Polohy byly načteny", Toast.LENGTH_LONG).show();
    }
}

1 个答案:

答案 0 :(得分:0)

崩溃发生是因为您正在尝试从后台线程创建新的Handler。尝试在主线程上创建它,例如:

public class LoadDataTask extends AsyncTask<Void, Void, List<Contact>> {
    private MainActivity mMainActivity;

    @Override
    protected void onPreExecute()
    {
        mMainActivity = new MainActivity();
    }

    @Override
    protected List<Contact> doInBackground(Void... voids)
    {
        return mMainActivity.Load();
    }

    @Override
    protected void onPostExecute(List<Contact> cont)
    {
        ...
    }
}