简体   繁体   English

在Android的AsyncTask的onPostExecute上显示alertDialog

[英]Display alertDialog onPostExecute of AsyncTask Android

I have an asyncTask and I want to show an alertDialog when the onPostExecute method is fired. 我有一个asyncTask ,我想在触发onPostExecute方法时显示一个alertDialog I declared a Context variable and I initialized it inside the OnCreate method like: 我声明了一个Context变量,并在OnCreate方法中对其进行了初始化,例如:

mContext = this;

Then in order to show the alertDialog on the onPostExecute method I used the following code: 然后,为了在onPostExecute方法上显示alertDialog ,我使用了以下代码:

            AlertDialog.Builder goLogin = new AlertDialog.Builder(mContext);
            goLogin.setMessage("test");
            goLogin.setCancelable(false);
            goLogin.setPositiveButton("ok",
                    new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
        AlertDialog alertLogin = goLogin.create();
        alertLogin.show();

But what I get is the following error: 但是我得到的是以下错误:

07-10 14:42:09.710: E/AndroidRuntime(12963): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:148)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:99)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:154)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.app.AlertDialog$Builder.<init>(AlertDialog.java:379)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at test.test.showAlert(test.java:671)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at test.test.checkResult(test.java:656)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at test.test$login.onPostExecute(test.java:585)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at test.test$login.onPostExecute(test.java:1)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.os.AsyncTask.finish(AsyncTask.java:632)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.os.Handler.dispatchMessage(Handler.java:102)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.os.Looper.loop(Looper.java:135)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at android.app.ActivityThread.main(ActivityThread.java:5312)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at java.lang.reflect.Method.invoke(Native Method)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at java.lang.reflect.Method.invoke(Method.java:372)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
07-10 14:42:09.710: E/AndroidRuntime(12963):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

What am I doing wrong? 我究竟做错了什么? Do I need to pass the context in a different way? 我是否需要以其他方式传递上下文?

EDIT: Whole AsyncTask code: 编辑:整个AsyncTask代码:

private class login extends AsyncTask<Void, Void, Void> {


@Override
protected void onPreExecute() {
    super.onPreExecute();
    // Showing progress dialog

}

@SuppressWarnings("deprecation")
@Override
protected Void doInBackground(Void... arg0) {
    // Creating service handler class instance
    ServiceHandler sh = new ServiceHandler();

    // Making a request to url and getting response
    List<NameValuePair> params = new ArrayList<NameValuePair>();

    params.add(new BasicNameValuePair("userName", "test"));
    String jsonStr = sh.makeServiceCall(urlTest, ServiceHandler.POST, params);


    if (jsonStr != null) {
        try {

            JSONObject obj = new JSONObject(jsonStr);

            error = obj.getBoolean("Error");
            if(!error)
            {
                loginResult = true;
                JSONObject array = obj.getJSONObject("Response");
                name = array.getString("Name");
            }
            else
            {
                loginResult = false;
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    } else {

    }

    return null;
}

@Override
protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    // Dismiss the progress dialog
    //checkResult();
    AlertDialog.Builder reorder = new AlertDialog.Builder(context);
    reorder.setMessage("error");
    reorder.setCancelable(true);
    reorder.setPositiveButton("ok",
            new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
        }
    });

    AlertDialog orderError = reorder.create();
    orderError.show();
}

}

Create constructor of your AsyncTask and do something like this: 创建AsyncTask的构造函数,然后执行以下操作:

private class DemoTask extends AsyncTask<Void, Void, Void> {
         Context context;

    public DemoTask(Context mContext) {
        this.context = mContext;
    }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            AlertDialog.Builder goLogin = new AlertDialog.Builder(context);
            goLogin.setMessage("test");
            goLogin.setCancelable(false);
            goLogin.setPositiveButton("ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
            AlertDialog alertLogin = goLogin.create();
            alertLogin.show();
        }

    }

Here mContext is inside onCreate Method: 这里的mContextonCreate方法里面:

public class MyActivity extends Activity {

private Context mContext;


@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;

        new DemoTask(mContext).execute();
    }

onPostExecute() is called on main thread. 在主线程上调用onPostExecute()。 mContext has Activity's context. mContext具有Activity的上下文。

Regardless of the fact Activity is destroyed or not, onPostExecute() will be called. 无论Activity是否被破坏,都会调用onPostExecute()。 When Activity is destroyed, the NPE error will occur while creating Alert Dialog Box. 销毁活动后,创建警报对话框时将发生NPE错误。 Make sure that Activity is on foreground. 确保活动位于前台。

update: 更新:

code: 码:

@Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            if(getActivity() == null)
            {
              return; //since activity is in background!
            }

            AlertDialog.Builder goLogin = new AlertDialog.Builder(context);
            goLogin.setMessage("test");
            goLogin.setCancelable(false);
            goLogin.setPositiveButton("ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
            AlertDialog alertLogin = goLogin.create();
            alertLogin.show();
        }

Before you get your servis callback in onPostExecute of your AsyncTask, user can send your app to background and your activity can be destroyed. 在AsyncTask的onPostExecute中获得servis回调之前,用户可以将您的应用发送到后台,并且您的活动可以被销毁。 In this case your context will be null and cannot show an alert dialog. 在这种情况下,您的上下文将为空,并且无法显示警报对话框。

I think it's not a good solution to show an alert dialog on AsyncTask results. 我认为在AsyncTask结果上显示警报对话框不是一个好的解决方案。 You can show a Toast message. 您可以显示Toast消息。 Dialogs use activity context and you can get this error. 对话框使用活动上下文,您会收到此错误。

Also can get BadTokenException in this kind of usage. 这种用法也可以得到BadTokenException。 To avoid these kind of errors check if your activity null and show dialog in a try catch blog. 为避免此类错误,请检查您的活动是否为空,并在try catch博客中显示对话框。

Remove last two line of code and add the below line : 删除最后两行代码,并添加以下行:

Instead of this line 代替这条线

AlertDialog alertLogin = goLogin.create();
alertLogin.show();

Use this line: 使用此行:

goLogin.show();

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

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