Android:使用Post方法到达AlertDialog.Builder时应用程序崩溃

问题描述:

我在使用正确文本的android应用程序中发出警报时出现问题。我使用相同的代码发送Get请求到服务器,它工作正常,但在这种情况下,我使用Post方法,而我发送的数据存储在数据库中,Logcat显示正确/预期的字符串来返回时,应用程序只会在onPostExecute部件崩溃而不显示警报时崩溃。Android:使用Post方法到达AlertDialog.Builder时应用程序崩溃

我错过了什么,有没有其他方式来处理来自Post方法的响应?

这里是我的代码:

package com.example.aplikacija; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.ArrayList; 
import java.util.List; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.protocol.BasicHttpContext; 
import org.apache.http.protocol.HttpContext; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.os.AsyncTask; 
import android.text.Html; 
import android.util.Log; 

public class REST_VpisOcene extends AsyncTask<Void, Void, String> { 

String restURL =  "*REST IP removed*"; 

private Activity activity; 
private String predmet; 
private String ocena; 
private String IDucenca; 
private String IDprofesorja; 

public REST_VpisOcene(String predmet, String ocena, String IDucenca, String IDprofesorja, 
     Activity activity) { 
    this.predmet = predmet; 
    this.ocena = ocena; 
    this.IDucenca = IDucenca; 
    this.IDprofesorja = IDprofesorja; 
    this.activity = activity; 
} 

protected String getASCIIContentFromEntity(HttpEntity entity) 
     throws IllegalStateException, IOException { 
    InputStream in = entity.getContent(); 
    StringBuffer out = new StringBuffer(); 
    int n = 1; 
    while (n > 0) { 
     byte[] b = new byte[4096]; 
     n = in.read(b); 
     if (n > 0) 
      out.append(new String(b, 0, n)); 
    } 
    return out.toString(); 
} 

@Override 
protected String doInBackground(Void... params) { 

    String sporocilo = ""; 
    HttpClient httpclient = new DefaultHttpClient(); 
    HttpContext localContext = new BasicHttpContext(); 
    HttpPost httppost = new HttpPost(restURL); 
    httppost.addHeader("Accept", "text/html"); 
    try { 
     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
     nameValuePairs 
       .add(new BasicNameValuePair("predmet", predmet)); 
     nameValuePairs.add(new BasicNameValuePair("ocena", ocena)); 
     nameValuePairs.add(new BasicNameValuePair("IDucenca", IDucenca)); 
     nameValuePairs.add(new BasicNameValuePair("IDprofesorja", IDprofesorja)); 
     httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

     HttpResponse response = httpclient.execute(httppost, localContext); 
     HttpEntity entity = response.getEntity(); 
     sporocilo = getASCIIContentFromEntity(entity); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    Log.i("odgovor vpisa", sporocilo); 
    return sporocilo; 

} 

protected void onPostExecute(String results) { 
    if (results.equals("0")) { 



     AlertDialog.Builder builder = new AlertDialog.Builder(activity); 
     builder.setMessage("Pri vpisu je prišlo do napake!") 
       .setCancelable(false) 
       .setNegativeButton("OK", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, 
            int id) { 
           dialog.cancel(); 
          } 
         }); 
     AlertDialog alert = builder.create(); 
     alert.show(); 
    } else if (results.equals("1")) { 

     AlertDialog.Builder builder = new AlertDialog.Builder(activity); 
     builder.setMessage("Vpisano!") 
       .setCancelable(false) 
       .setNegativeButton("OK", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, 
            int id) { 
           dialog.cancel(); 
          } 
         }); 
     AlertDialog alert = builder.create(); 
     alert.show(); 
    } 
} 
} 

而且我的logcat:

02-08 14:56:11.856: I/odgovor vpisa(6424): 1 
02-08 14:56:11.859: D/AndroidRuntime(6424): Shutting down VM 
02-08 14:56:11.860: E/AndroidRuntime(6424): FATAL EXCEPTION: main 
02-08 14:56:11.860: E/AndroidRuntime(6424): Process: com.example.aplikacija,  PID: 6424 
02-08 14:56:11.860: E/AndroidRuntime(6424): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:154) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.app.AlertDialog$Builder.<init>(AlertDialog.java:379) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at com.example.aplikacija.REST_VpisOcene.onPostExecute(REST_VpisOcene.java:121) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at com.example.aplikacija.REST_VpisOcene.onPostExecute(REST_VpisOcene.java:1) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.os.AsyncTask.finish(AsyncTask.java:632) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.os.AsyncTask.access$600(AsyncTask.java:177) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.os.Handler.dispatchMessage(Handler.java:102) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.os.Looper.loop(Looper.java:135) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at android.app.ActivityThread.main(ActivityThread.java:5221) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at java.lang.reflect.Method.invoke(Native Method) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at java.lang.reflect.Method.invoke(Method.java:372) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
02-08 14:56:11.860: E/AndroidRuntime(6424):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

它未能就行了121,这是在第二个if从句

AlertDialog.Builder builder = new AlertDialog.Builder(activity); 

,这意味着它通过

results.equals("1") 

检查,在它失败之前。

谢谢。

问题是,在调用onPostExecute()的那一刻不保证活动存在。

onPostExecute()是在完成后台线程处理后调用的方法,与Activity的生命周期无关。

解决方案是检查当时是否存在活动,然后执行预期的逻辑。

您可以看到this以获得更详细的答案(不同的情况,但都与您在此处遇到的核心问题有关)。还有一个博客文章详细说明了这个主题,这个主题是here

变化private Activity context;private Context context

public REST_VpisOcene(String predmet, String ocena, String IDucenca, String IDprofesorja, 
     Context context) { 
    this.predmet = predmet; 
    this.ocena = ocena; 
    this.IDucenca = IDucenca; 
    this.IDprofesorja = IDprofesorja; 
    this.context= context; 
} 

或使用getApplicationContext(),而不是背景也看到this Question

时隔一年,但如果别人有这个问题,也许这个解决方案可以帮助

当活动要显示对话框或需要活动上下文的任何操作时,检查活动是否可见是很重要的。

要做到这一点,你需要从应用程序扩展类:

public class App extends Application { 

    private static Context mContext; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mContext = this; 
    } 

    public static Context getContext(){ 
     return mContext; 
    } 

    public static boolean isActivityVisible() { 
     return activityVisible; 
    } 

    public static void activityResumed() { 
     activityVisible = true; 
    } 

    public static void activityPaused() { 
     activityVisible = false; 
    } 

    private static boolean activityVisible; 
} 

在您的MainActivity类别,您需要注册该应用程序的当前状态,当一些这些动作的完成:

@Override 
protected void onResume() { 
    super.onResume(); 
    App.activityResumed(); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    App.activityPaused(); 
} 

最后,做这样显示对话框一些行动之前,只是检查,如果应用程序是可见的:

if (App.isActivityVisible()) { 
    // We can show the dialog 
} else { 
    // Better not show the dialog to avoid a crash 
} 

祝您有美好的一天! :)