java - AsyncTask 返回值延迟

标签 java android google-app-engine android-asynctask google-cloud-datastore

我有一个带有电子邮件字段和按钮的身份验证界面。 当我点击按钮时,AsyncTask 应该验证电子邮件是否存在于谷歌应用引擎数据存储中。 这是我的异步任务的代码:

public class ConnexionAsyncTask extends AsyncTask<Object, Object, Inscrit> {
private static InscritApi inscritApi = null;
private Context context;
String email;
ProgressDialog dialog;


public ConnexionAsyncTask(Context context, String email) {
    this.context = context;
    dialog = new ProgressDialog(context);
    this.email = email;
}

@Override
protected void onPreExecute() {
    dialog.setMessage("Connexion en cours");
    dialog.setIndeterminate(true);
    dialog.setCancelable(false);
    dialog.show();
}

@Override
protected Inscrit doInBackground(Object... params) {
    if (inscritApi == null) {
        InscritApi.Builder builder = new InscritApi.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null)
                .setRootUrl( // some url );
        inscritApi = builder.build();
    }
    try {
        return inscritApi.get(email).execute();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onPostExecute(Inscrit inscrit) {
    MainActivity main = (MainActivity) context;
    main.setInscrit(inscrit);
    dialog.dismiss();
}}

这是 MainActivity 代码:

public class MainActivity extends AppCompatActivity {

Inscrit inscrit;
Button btncnx;
EditText emailcnx;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btncnx = (Button) findViewById(R.id.btncnx);
    emailcnx = (EditText) findViewById(R.id.emailcnx);
    btncnx.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ConnexionAsyncTask task = new ConnexionAsyncTask(MainActivity.this, emailcnx.getText().toString());
            task.execute();
            if (inscrit == null)
                Toast.makeText(MainActivity.this, "not exist", Toast.LENGTH_SHORT).show();
            else
                Toast.makeText(MainActivity.this, "exist", Toast.LENGTH_SHORT).show();
        }
    });
}
public void setInscrit(Inscrit inscrit) {
    this.inscrit = inscrit;
}}

所以代码应该像这样工作:

  1. MainActivity 应该将“inscrit”变量提供给 ConnexionAsyncTask
  2. ConnexionAsyncTask 应该验证电子邮件是否存在于数据存储中,然后将结果(Inscrit 实例或 null)放入带有 setter 的“inscrit”变量中
  3. MainActivity 应该验证“inscrit”是否为 null 并显示 toast

当我运行我的代码时,我必须单击 2 次才能获得真实结果,例如,如果我输入“user@gmail.com”并且这封电子邮件当然存在于数据存储区中,它将显示“不存在” first time and exist for second 这意味着 AsyncTask 在验证后立即返回值。 如果我用 .execute().get() 返回值,它可以工作,但它会阻塞 ui 线程,我想显示一个进度对话框。 我试过使用回调接口(interface),但它也不起作用。

最佳答案

你应该做检查

if (inscrit == null)
   Toast.makeText(MainActivity.this, "not exist", Toast.LENGTH_SHORT).show();
else
   Toast.makeText(MainActivity.this, "exist", Toast.LENGTH_SHORT).show();

在您的 AsyncTask 完成执行之后。基本上,您可以安全地在 PostExecute 上检查 inscrit 可空性。

关于java - AsyncTask 返回值延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39549235/

相关文章:

java - 是否可以允许非本地主机客户端访问 App Engine Servlet 的本地实现?

java.rmi.NoSuchObjectException 但添加了静态引用

java - 如何在程序中使用存储在mysql的varchar字段中的utf8mb4符号而不改变mysql的字段

java - 如何使用Java将用户提供的图片保存到数据库

android - 如何在 fragment 中膨胀 LinearLayout?

google-app-engine - 在 Google Compute Engine 上扩展 WebSocket

java - 删除字符串的第一个字符 O(1)

java - Exoplayer ui分屏添加双击前进/后退循环效果

android - 在列表的上下文菜单中,字符串太长并被截断

java - 使用 POST 将数据从 Android 发送到 AppEngine Datastore