0

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

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

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

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

4

4 回答 4

5

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

于 2012-10-03T14:27:53.893 回答
0

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

于 2012-10-03T14:32:21.500 回答
0

你可以在你的 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
        }
    }
}
于 2012-10-03T14:32:31.233 回答
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
)   
}
}
于 2016-03-15T17:27:54.000 回答