【问题标题】:How to access SQLite database from UI thread if I'm inserting data in AsyncTask thread?如果我在 AsyncTask 线程中插入数据,如何从 UI 线程访问 SQLite 数据库?
【发布时间】:2012-09-24 12:01:56
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你能用代码显示你在做什么吗?
  • 当然可以。这就是 onPostExecute 的用途。在你的 asynctask 完成它必须做的事情之后在 ui 线程上执行东西

标签: android sqlite android-asynctask


【解决方案1】:

UI 线程是您的应用程序主线程。当您创建AsyncTask 时,您的耗时任务将在单独的线程上执行(在doInBackground 函数内)。当doInBackground 完成时,将从UI 线程调用onPostExecute()。因此,您只需从onPostExecute() 内部执行您的 UI 线程任务(=“恢复该数据并使用它来打开提到的活动”)。

【讨论】:

    【解决方案2】:

    我认为你之前的做法是正确的。我建议进行一种 SplashScreen 活动,检查用户之前是否登录过,即数据库中是否有用户名/密码。如果是这种情况,请使用此数据登录用户,然后继续您的主要活动。如果用户之前没有登录过,请使用登录屏幕提示他们,存储此数据以供将来使用并继续您的主要活动。

    【讨论】:

      【解决方案3】:

      你可以在你的 UIThread 中实现一个 BroadcastReciever,当插入数据库完成时,它会监听从你的 AsyncTask 发送的 Intent。

      从 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
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        您必须记住,一旦您启动 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
        )   
        }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-10
          • 2011-06-01
          • 2017-04-28
          • 1970-01-01
          • 1970-01-01
          • 2018-02-09
          • 2012-02-15
          相关资源
          最近更新 更多