AsyncTask存在XML文件创建问题

时间:2013-09-15 19:02:03

标签: android

我正在制作一个类似测验的应用。

当您选择答案并将其交给后台的下一个应该发送响应xml文件并转到下一个问题(活动)

这是调用后台任务并传递第二个活动的活动的代码

if(options == "0") ans.setText("Must select an answer");
        else {

           Intent intent =
                 new Intent(PM1_1Activity.this, PM1_2Activity.class);


           AsyncLoadXML carga = new AsyncLoadXML(PM1_1Activity.this);
           carga.execute();

           startActivity(intent);
           finish();

        }

这是创建后台任务的类的代码

    package com.asde.ipac;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Xml;
import android.widget.Toast;

class AsyncLoadXML extends AsyncTask<Void, Integer, Boolean> {

   Context ctx;



   public AsyncLoadXML(Context c) {
      this.ctx = c;

   }

   @Override
   protected Boolean doInBackground(Void... params) {



      try {
         writeXML(ctx);
      } catch (IOException e) {

         e.printStackTrace();
      }

      return null;
   }


   public void writeXML(Context ctx) throws IOException{   
      FileOutputStream fout = null;

      try {
         fout = ctx.openFileOutput("answers.xml", Context.MODE_PRIVATE);
      } catch (FileNotFoundException e) {
         Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_LONG).show();
      }

      XmlSerializer serializer = Xml.newSerializer();
      try {
         serializer.setOutput(fout, "UTF-8");
         serializer.startDocument(null, true);
         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

         serializer.startTag(null, "questions");

         serializer.startTag(null, "question");
         serializer.attribute(null,"grupo" , "test");
         serializer.attribute(null,"grupo" , "test");
         serializer.text("A");
         serializer.endTag(null, "question");



         serializer.endTag(null, "questions");


         serializer.endDocument();
         serializer.flush();
         fout.close();

         Toast.makeText(ctx, "write done", Toast.LENGTH_LONG).show();
      } catch (Exception e) {
         Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_LONG).show();
      }
   }



}

这是LogCat的输出

    09-15 14:34:04.151: E/AndroidRuntime(1225): FATAL EXCEPTION: AsyncTask #5
09-15 14:34:04.151: E/AndroidRuntime(1225): java.lang.RuntimeException: An error occured while executing doInBackground()
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.lang.Thread.run(Thread.java:841)
09-15 14:34:04.151: E/AndroidRuntime(1225): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.os.Handler.<init>(Handler.java:197)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.os.Handler.<init>(Handler.java:111)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.widget.Toast$TN.<init>(Toast.java:324)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.widget.Toast.<init>(Toast.java:91)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.widget.Toast.makeText(Toast.java:238)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at com.asde.ipac.AsyncLoadXML.escribirXML(AsyncLoadXML.java:96)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at com.asde.ipac.AsyncLoadXML.doInBackground(AsyncLoadXML.java:43)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at com.asde.ipac.AsyncLoadXML.doInBackground(AsyncLoadXML.java:1)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-15 14:34:04.151: E/AndroidRuntime(1225):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-15 14:34:04.151: E/AndroidRuntime(1225):    ... 4 more

不,我做错了。 OnPostExecute方法是强制性的吗?

非常感谢

2 个答案:

答案 0 :(得分:1)

问题是您尝试在doInBackground()中显示Toasts,而此方法中禁止UI操作。

您应该做的是在此方法中进行所有处理,返回处理结果,然后在onPostExecute()处理它并在必要时显示Toasts。

修改

类似的东西:更改writeXML的返回值:

public String writeXML(Context ctx) throws IOException{   
  FileOutputStream fout = null;

  try {
     fout = ctx.openFileOutput("answers.xml", Context.MODE_PRIVATE);
  } catch (FileNotFoundException e) {
     return e.getMessage();
  }

  XmlSerializer serializer = Xml.newSerializer();
  try {
     serializer.setOutput(fout, "UTF-8");
     serializer.startDocument(null, true);
     serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

     serializer.startTag(null, "questions");

     serializer.startTag(null, "question");
     serializer.attribute(null,"grupo" , "test");
     serializer.attribute(null,"grupo" , "test");
     serializer.text("A");
     serializer.endTag(null, "question");



     serializer.endTag(null, "questions");


     serializer.endDocument();
     serializer.flush();
     fout.close();

     return "write done";
  } catch (Exception e) {
     return e.getMessage();
  }
  }

同时更改doInBackground的返回值:(您还必须更改AsyncTask声明:class AsyncLoadXML extends AsyncTask<Void, Integer, String>

   @Override

   protected String doInBackground(Void... params) {
       String result = "";

       try {
           result = writeXML(ctx);
       } catch (IOException e) {

          e.printStackTrace();
       }

       return result;
   }

并添加onPostExecute方法:

protected void onPostExecute(String result) {
    if(!result.equals("")) 
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}

答案 1 :(得分:0)

查看您的日志:

Can't create handler inside thread that has not called Looper.prepare()

Looper.prepare();添加到运行Handler的线程

通过处理程序与Thread UI一起使用迭代,例如:

private Handler mHandler = null;
protected static final int TOAST = 1;

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        String txt;
        switch (msg.what) {
        case TOAST:
            txt = msg.obj.toString();
            Toast.makeText(ctx, txt, Toast.LENGTH_LONG).show();
            break;          
        default:
            super.handleMessage(msg);
        }           



    }
};

现在您可以使用处理程序显示您的祝酒词:

mHandler.sendMessage(mHandler.obtainMessage(TOAST, "write done"));

就像jbihan所说,把你的逻辑放在onPostExecute()

下显示Toast的地方

因为在doInBackground下的Toast下丢失了您的错误