无法在未使用AsyncTask调用Looper.prepare()的线程内创建处理程序

时间:2012-02-20 07:21:52

标签: android android-asynctask

我正在尝试在Android上使用AsyncTask类,但我遇到了问题。

这是我的代码:

 public void CheckIfUserIsLogedIn ()
{
    int userPresence = localDatabase.CheckUserPresence();
    if (userPresence == 0) 
    {
        setContentView(R.layout.main);
        new checkCountryAsync().execute();
    }
    else
    {
        setContentView(R.layout.userlogedon);
    }
}  

class checkCountryAsync extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute(); 
    }
    @Override
    protected String doInBackground(String... aurl) {
        int countryPresence = localDatabase.CheckCountryPresence();
        if (countryPresence == 0) 
        {
            CountryTable country = new CountryTable() ;
            country.EnterCountry();
        }
        return null;
    }
}

我不知道我在哪里做错了什么。 LocalDatabase类中的方法CheckCountryPresence()仅进行查询并返回结果。

谢谢。

编辑:这是logCat:

02-20 08:41:25.804: W/dalvikvm(26458): threadid=10: thread exiting with uncaught exception (group=0x4001d5a0)
02-20 08:41:25.834: E/AndroidRuntime(26458): FATAL EXCEPTION: AsyncTask #1
02-20 08:41:25.834: E/AndroidRuntime(26458): java.lang.RuntimeException: An error occured while executing doInBackground()
02-20 08:41:25.834: E/AndroidRuntime(26458):    at android.os.AsyncTask$3.done(AsyncTask.java:200)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.lang.Thread.run(Thread.java:1027)
02-20 08:41:25.834: E/AndroidRuntime(26458): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
02-20 08:41:25.834: E/AndroidRuntime(26458):    at android.os.Handler.<init>(Handler.java:121)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at android.app.Activity.<init>(Activity.java:717)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at milos.mdpi.CountryTable.<init>(CountryTable.java:5)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at milos.mdpi.MDPIActivity$checkCountryAsync.doInBackground(MDPIActivity.java:367)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at milos.mdpi.MDPIActivity$checkCountryAsync.doInBackground(MDPIActivity.java:1)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-20 08:41:25.834: E/AndroidRuntime(26458):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
02-20 08:41:25.834: E/AndroidRuntime(26458):    ... 4 more

4 个答案:

答案 0 :(得分:6)

似乎你正在通过Update线程向你的用户界面Non-UI做一些事情。所以,你应该把你的东西更新到runOnUiThread()里面的UI,这样它就可以在你自己的UI上执行这些东西。

<强>更新

尝试将您的内容放入CheckCountryPresence(); onPreExecute()。所以你编辑的课应该是,

class checkCountryAsync extends AsyncTask<String, String, String> {

    int countryPresence = 0;
    @Override
    protected void onPreExecute() {
       countryPresence = localDatabase.CheckCountryPresence();
    }
    @Override
    protected String doInBackground(String... aurl) {

        Activity_name.this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            if (countryPresence == 0) 
            {
              CountryTable country = new CountryTable() ;
              country.EnterCountry();
            }
        }
    });
        return null;
    }
}

答案 1 :(得分:3)

您的CountryTable类是否与UI活动/类进行任何交互?甚至为适配器对象获取新行? 如果是,则无法从活动本身之外更新您的活动。

幸运的是,一旦找到解决方案,你就可以很容易地克服这个问题;)

第1步:

使用名为CheckCountryCallback;

的单一方法定义一个界面,例如onCheckCountryFinished(String taskResult)

步骤2:让调用你的asynctask的活动实现这个接口及其方法。

步骤3:使用CheckCountryCallback类型的单个参数为asyncTask定义构造函数

步骤4:覆盖AT的onPostExecute,只需编写mCaller.onCheckCountryFinished(结果)。

这还不够,因为你仍然会从另一个线程更新ui,但我们已经接近了!

在您实施的onCheckCountryFinished中,您应该将调用重定向到您要在活动中定义的处理程序。向该处理程序发送消息,您可以从处理程序的句柄消息方法更新UI(或适配器或诸如此类的东西)。

处理程序示例:

private static final int UPDATE = 2;
private Handler handler = new Handler() {

    public void handleMessage(Message msg) {
        if (msg.what == UPDATE) {
               //do something with m.obj
               myAdapter.notifyDataSetChanged();
        }
    }
};

回调示例

public void onCheckCountryFinished(String result){
    Message m = Message.obtain();
    m.what = UPDATE;
    m.obj = result;
    handler.sendMessage(m);
}

答案 2 :(得分:2)

您没有传递任何AsyncTask,所以将AsyncTask的参数全部设为Void,如AsyncTask<Void, Void, Void>,然后将doInBackground更改为此protected Void doInBackground(Void... voids)。另外,摆脱onPreExecute方法,因为你甚至没有使用它。

此外,您不清楚提供的代码,但需要从UI线程调用CheckIfUserIsLogedIn。 AsyncTask实际上只是用于运行UI线程。

答案 3 :(得分:1)

我遇到的问题之一,simpleCursorAdapter在从looper调用时也会返回thread的同一错误。所以要在线程

中删除该错误
ActivityName.this.runOnUiThread(new Runnable() {
 public void run() {
   String[] FROM = {/*your data here*/};
int[] TO = { /*your data here*/ };
adapter = new SimpleCursorAdapter(ActivityName.this, R.layout.row, cursor, FROM, TO);   
listTimeline.setAdapter(adapter); //your own code here.
}
});