我正在尝试在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
答案 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.
}
});