繁体   English   中英

在Android的AsyncTask的onPostExecute上显示alertDialog

[英]Display alertDialog onPostExecute of AsyncTask Android

我有一个asyncTask ,我想在触发onPostExecute方法时显示一个alertDialog 我声明了一个Context变量,并在OnCreate方法中对其进行了初始化,例如:

mContext = this;

然后,为了在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();

但是我得到的是以下错误:

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)

我究竟做错了什么? 我是否需要以其他方式传递上下文?

编辑:整个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();
}

}

创建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();
        }

    }

这里的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()。 mContext具有Activity的上下文。

无论Activity是否被破坏,都会调用onPostExecute()。 销毁活动后,创建警报对话框时将发生NPE错误。 确保活动位于前台。

更新:

码:

@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();
        }

在AsyncTask的onPostExecute中获得servis回调之前,用户可以将您的应用发送到后台,并且您的活动可以被销毁。 在这种情况下,您的上下文将为空,并且无法显示警报对话框。

我认为在AsyncTask结果上显示警报对话框不是一个好的解决方案。 您可以显示Toast消息。 对话框使用活动上下文,您会收到此错误。

这种用法也可以得到BadTokenException。 为避免此类错误,请检查您的活动是否为空,并在try catch博客中显示对话框。

删除最后两行代码,并添加以下行:

代替这条线

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

使用此行:

goLogin.show();

暂无
暂无

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

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