无法在未使用 AsyncTask 调用 Looper.prepare() 的线程内创建处理程序
我正在尝试在 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
I am trying to use the AsyncTask class on android but I have a problem.
Here is my code:
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;
}
}
I don't know where I am doing something wrong. The method CheckCountryPresence() from the LocalDatabase class is only making a query and returns a result.
Thank you.
Edit: Here is the 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
似乎您正在做一些事情来从
非 UI
线程更新
您的 UI。因此,您应该将要更新 UI 的内容放入runOnUiThread()
中,以便它在您的 UI 线程本身上执行这些内容。更新:
只需尝试将获取
CheckCountryPresence();
的内容放入onPreExecute()
中即可。所以你编辑的课程应该是这样的,Seems you are doing some stuff to
Update
your UI from aNon-UI
thread. So, you should put your stuff to update the UI insiderunOnUiThread()
so that it executes the stuff on your UI hread itself.UPDATE:
Just try to put your stuff for getting
CheckCountryPresence();
insideonPreExecute()
. So your edited class should be like,您的 CountryTable 类与 UI 活动/类有任何交互吗?甚至为您的适配器对象获取新行?
如果是,您无法从活动本身外部更新您的活动。
幸运的是,一旦找到解决方案,您就可以轻松克服这个问题;)
第 1 步:
定义一个接口,例如使用名为
onCheckCountryFinished(String taskResult)
的单个方法定义一个接口,例如CheckCountryCallback
;步骤2:让调用你的asynctask的活动实现这个接口及其方法。
步骤 3:使用 CheckCountryCallback 类型的单个参数为 asyncTask 定义一个构造函数
步骤 4:重写 AT 的 onPostExecute,并简单地编写 mCaller.onCheckCountryFinished(result)。
遗憾的是,这还不够,因为您仍然需要从另一个线程更新 ui,但我们已经很接近了!
在实现的 onCheckCountryFinished 中,您应该将调用重定向到您在活动中定义的处理程序。向该处理程序发送消息,您可以通过处理程序的处理消息方法更新 UI(或适配器或其他内容)。
处理程序示例:
回调示例
Has your CountryTable class any interaction with the UI activity/class? Even fetching new rows for your adapter object?
If yes, you cannot update your activity from outside the activity itself.
Fortunately you can overcome this pretty easily once you figure out the solution ;)
step 1:
Define an interface, like
CheckCountryCallback
with a single method calledonCheckCountryFinished(String taskResult)
;Step 2: let the activity which call your asynctask implement this interface and its method.
Step 3: define a constructor for your asyncTask with a single parameter of type CheckCountryCallback
Step 4: override onPostExecute of your AT, and simply write mCaller.onCheckCountryFinished(result).
This is not enough sadly because you'd still be updating the ui from another thread but we're getting close!
In your implemented onCheckCountryFinished you should redirect the call to a handler you've to define in your activity. Send a message to that handler and you can update the UI (or the adapter or whatnot) from the handle message method of the handler.
Handler example:
callback example
您没有向 AsyncTask 传递任何内容,因此请将 AsyncTask 的参数设置为 Void,如下所示
AsyncTask
然后将doInBackground
更改为此protected Void doInBackground (无效...无效)
。另外,摆脱onPreExecute
方法,因为您甚至没有使用它。另外,您提供的代码还不清楚,但需要从 UI 线程调用
CheckIfUserIsLogedIn
。 AsyncTask 实际上只是在 UI 线程上运行。You are not passing your AsyncTask anything so make the parameters of AsyncTask all Void like this
AsyncTask<Void, Void, Void>
then changedoInBackground
to thisprotected Void doInBackground(Void... voids)
. Also, get rid of theonPreExecute
method since you are not even using it.Also, it is unclear with you code provided, but
CheckIfUserIsLogedIn
needs to be called from the UI thread. AsyncTask is really only meant to be run off of the UI thread.我遇到的问题之一是,当从
thread
调用时,simpleCursorAdapter
也会返回相同的looper
错误。因此,要消除该错误,请使用内部线程one of the problem that i faced,
simpleCursorAdapter
also returns same error oflooper
when called fromthread
. So to remove that error, inside thread