![](/img/trans.png)
[英]Handle NPE Gracefully and Display AlertDialog in OnPostExecute / AsyncTask When Internet Connection Is Lost - Android / Java
[英]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();
}
}
这里的mContext
在onCreate
方法里面:
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.