简体   繁体   English

等待AsyncTask完成

[英]Wait for AsyncTask to finish

Hi I'm making Login page that access MySQL database. 嗨,我正在制作访问MySQL数据库的登录页面。 But my Activity always runs the code that check fail/success before it finishes the AsyncTask . 但是我的Activity总是在完成AsyncTask之前运行检查失败/成功的代码。

I tried using asynctask.get() method, but it just freeze my UI and doesn't work. 我尝试使用asynctask.get()方法,但是它只是冻结了我的UI,无法正常工作。

I tried this answer that said I should call the result-checker method inside onPostExecute() . 我尝试了这个答案 ,说我应该在onPostExecute()调用result-checker方法。

But since I need to change the TextView to show success/failed, it results in NullPointerException because I instantiate the TextView inside onCreate() . 但是由于我需要更改TextView才能显示成功/失败,所以会导致NullPointerException因为我在onCreate()实例化了TextView。

I can't move the TextView instantiation into constructor because it will return NullPointerException unable to instantiate activity ComponentInfo . 我无法将TextView实例化移动到构造函数中,因为它将返回NullPointerException unable to instantiate activity ComponentInfo

Login.java Login.java

public class Login extends Activity{

    //declare global Views here

    protected void onCreate(Bundle bundle){
        //Setup views
    }

    protected void onClick(View v){
        //Setup necessary variables
        AsyncClass async = new AsyncClass(this);
        async.execute(username, password);
    }

    public void checkSuccess(boolean success){
        if(success)
            textView1.setText("Success");
        else
            textView1.setText("Failed");
    }
}

AsyncClass.java AsyncClass.java

public class AsyncClass extends AsyncTask<String, String, JSONObject>{
    protected JSONObject doInBackground(String... params){
        //access database
    }

    protected void onPostExecute(JSONObject json){
        //read the json result
        Login login = new Login();
        login.checkSuccess(true);
    }
}

Any solution? 有什么办法吗? Thanks 谢谢

How about making AsyncTask as your inner class? 如何将AsyncTask用作您的内部类?

So your code should look something like below. 因此,您的代码应如下所示。

public class Login extends Activity {

    //declare global Views here

    protected void onCreate(Bundle bundle) {
        //Setup views
    }

    protected void onClick(View v) {
        new AsyncClass().execute(username, password);
    }

    public void checkSuccess(boolean success) {
        if (success) textView1.setText("Success");
        else textView1.setText("Failed");
    }

    class AsyncClass extends AsyncTask < String, String, JSONObject > {
        protected JSONObject doInBackground(String...params) {
            //access database
        }

        protected void onPostExecute(JSONObject json) {
            checkSuccess(true / false);
        }
    }
}

try this 尝试这个

protected void onPostExecute(JSONObject json){
    //read the json result
    Login login = (Login)context; // object that you pass to task constructor
    login.checkSuccess(true);
}

Also you can add progress dialog to your task to indicate some job execution 您也可以在任务中添加进度对话框以指示一些作业执行

public class BaseTask<T> extends AsyncTask<Object, Void, T> {

public Context context;
public ProgressDialog dialog;

public BaseTask(Context context) {
    this.context = context;
    this.dialog = new ProgressDialog(context);
}

@Override
protected void onPreExecute() {
    this.dialog.setMessage(context.getResources().getString(R.string.loading));
    this.dialog.show();

}

@Override
protected T doInBackground(Object... objects) {
    //....
    return something;
}

@Override
protected void onPostExecute(T result) {
    if (dialog != null && dialog.isShowing())
        dialog.dismiss();
    // do something
}

} }

You cannot edit the UI from the async task thread. 您无法从异步任务线程编辑UI。 In order to make updates to the UI thread, use the onProgressUpdate() method. 为了更新UI线程,请使用onProgressUpdate()方法。 This method is part of your AsyncTask class, is actually executed in the main UI Thread (I hope you use the async task as a nested class btw, since it is declared public I guess your not. You should change that). 此方法是AsyncTask类的一部分,实际上是在主UI线程中执行的(我希望您将async任务用作嵌套类btw,因为它被声明为public,我想您不是。您应该对此进行更改)。 The onProgressUpdate() Method is called by the OS itself if you call publishProgress(...) inside your Async task. 如果您在Async任务中调用publishProgress(...),则OS本身将调用onProgressUpdate()方法。

A small sample: 一个小样本:

protected JSONObject doInBackground(String... params){
    publishProgress("test");
}

    /**
     * This method is part of the Async Task
     */
    protected void onProgressUpdate(String... progress) {
        login.checkSuccess(true);
    }   

I would use it this way, just override your onPostExecute where you need it or create a own interface 我将以这种方式使用它,只需在需要时覆盖onPostExecute或创建自己的接口

//create a object f your asyncclass and 
//override the onPostExecute where you need it
mInfo = new ASYNCCLASS({
   @Override
   public void onPostExecute(Object result){
      //doSomething something with your views!

  }
}).execute();

Waiting is not the answer, because you do not know how long your Asynctask will take to end. 等待不是答案,因为您不知道Asynctask将花费多长时间。 Code above is not tested, just pseudoce, but it should show what i mean. 上面的代码没有经过测试,只是伪造的,但是它应该表明我的意思。

Do not have my IDE round here, so if anybody would correct the brackets if neccessary would be great! 我的IDE不在这里,所以如果有人愿意,可以改正括号!

Greetz 格蕾兹

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM