我的Android应用程序中有一个名为Main.java的类,用于根据我服务器中的数据验证用户登录名(用户名+密码)。起初,我成功了;我使用AsyncTask线程加上一个处理Http连接的库,调用HttpPostAux.java(实际上,我在这个论坛中找到了库的代码)。在AsyncTask的onPostExecute方法中,我创建并启动了一个新活动,而不是修改当前活动并且它有效。
但现在我想做不同的事情。我想将验证的数据(用户名+密码)保存到AsyncTask线程中的SQLite表中,然后在UI线程中,恢复该数据并使用它来打开上述活动。插入发生但当我尝试从UI线程访问数据库时:它表示该表为空。所以我查看了logcat,发现UI线程在AsyncTask线程之前执行。
所以我的问题是如何在AsyncTask线程中插入数据然后在UI线程内恢复?有人可以帮忙吗?我有点迷路了!
我将欣赏一个代码示例!提前致谢! 来自委内瑞拉的问候!
答案 0 :(得分:5)
UI线程是您的应用程序主线程。当您创建AsyncTask
时,将在单独的线程上执行您的长时间执行任务(在doInBackground
函数内)。 doInBackground
完成后,将从UI线程调用onPostExecute()
。因此,您只需要从onPostExecute()
内执行您的UI线程任务(=“恢复该数据并使用它来打开上述活动”)。
答案 1 :(得分:0)
我认为你之前的做法是正确的。我建议做一种SplashScreen活动,检查用户之前是否已经登录,即数据库中是否有用户名/密码。如果是这种情况,请使用此数据登录用户,然后继续进行主要活动。如果用户之前尚未登录,请使用登录屏幕提示他们,存储此数据以备将来使用,并继续进行主要活动。
答案 2 :(得分:0)
您可以在UIThread中实现一个BroadcastReciever,它可以在完成对数据库的插入操作时侦听从AsyncTask发送的Intents。
来自AsyncTask:
Intent intent = new Intent("DATABASE_INSERTION_DONE");
context.sendBroadcast(intent );
在UiThread中注册:
IntentFilter intentFilter = new IntentFilter("DATABASE_INSERTION_DONE");
registerReceiver(myIntentsReceiver, intentFilter);
类:
class MyIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("DATABASE_INSERTION_DONE".equals(intent.getAction())) {
//do something
}
}
}
答案 3 :(得分:0)
您必须记住,一旦启动AsyncTask,它将在另一个线程上运行,您的UI线程将继续向前发展。例如:
x="foo";
new SampleAsyncTask().execute();
txtView.setText(x);
Class SampleAsyncTask extends AsyncTask<...>{
.....
public Void doInBackground(...){
//LOTS OF CALCULATIONS
x="bar";
}
}
你的txtView绝对会显示“foo”而不是“bar”。为了确保您的AsyncTask完成,有很多选项。您可以调用方法在AsyncTask的PostExecute中启动其余操作。你也可以使用意图和Jelgh所说的广播接收器。但我最喜欢的是使用简单的回调:
public class LoginActivity extends Activity implement SampleAsyncTask.asyncCallback{
@Override
protected void onCreate(Bundle savedInstanceState){
x="foo";
new SampleAsyncTask().execute();
Class SampleAsyncTask extends AsyncTask<...>{
asyncCallback mCallback;
public SampleAsyncTask(Context c){
mCallback; = (asyncCallback) c
}
public interface asyncCallback{
void servedMyPurposeYouCanGoOn();
}
public Void doInBackground(...){
//LOTS OF CALCULATIONS
x="bar";
mCallback.servedMyPurposeYouCanGoOn;
//REST OF THE WORK
}
}
}
@Override
public void servedMyPurposeYouCanGoOn(){
runOnUIThread(
//rest of the work
)
}
}