如果我在AsyncTask线程中插入数据,如何从UI线程访问SQLite数据库?

时间:2012-10-03 14:22:39

标签: android sqlite android-asynctask

我的Android应用程序中有一个名为Main.java的类,用于根据我服务器中的数据验证用户登录名(用户名+密码)。起初,我成功了;我使用AsyncTask线程加上一个处理Http连接的库,调用HttpPostAux.java(实际上,我在这个论坛中找到了库的代码)。在AsyncTask的onPostExecute方法中,我创建并启动了一个新活动,而不是修改当前活动并且它有效。

但现在我想做不同的事情。我想将验证的数据(用户名+密码)保存到AsyncTask线程中的SQLite表中,然后在UI线程中,恢复该数据并使用它来打开上述活动。插入发生但当我尝试从UI线程访问数据库时:它表示该表为空。所以我查看了logcat,发现UI线程在AsyncTask线程之前执行。

所以我的问题是如何在AsyncTask线程中插入数据然后在UI线程内恢复?有人可以帮忙吗?我有点迷路了!

我将欣赏一个代码示例!提前致谢! 来自委内瑞拉的问候!

4 个答案:

答案 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
)   
}
}