Android 为什么我会收到一封“信”;线程退出时出现未捕获异常”;?

Android 为什么我会收到一封“信”;线程退出时出现未捕获异常”;?,android,serialization,parse-platform,Android,Serialization,Parse Platform,我正在使用Parse.com进行推送通知。当我收到推送通知时,该类执行: public class MyCustomReceiver extends BroadcastReceiver { protected ObjetoMensaje DatosObjecto; protected SerializacionDeDatos Sdd; protected String alert, fecha, name, tipo; private static final

我正在使用Parse.com进行推送通知。当我收到推送通知时,该类执行:

public class MyCustomReceiver extends BroadcastReceiver {

    protected ObjetoMensaje DatosObjecto;
    protected SerializacionDeDatos Sdd;
    protected String alert, fecha, name, tipo;
    private static final String TAG = "MyCustomReceiver";

  @Override
  public void onReceive(Context context, Intent intent) {
    try {

        DatosObjecto = new ObjetoMensaje();
        Sdd = new SerializacionDeDatos();

      String action = intent.getAction();
      String channel = intent.getExtras().getString("com.parse.Channel");
      JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));

      Log.d(TAG, "got action " + action + " on channel " + channel + " with:");
      Iterator<?> itr = json.keys();
      Log.i("","");

      while (itr.hasNext()) {
        String key = (String) itr.next();
        Log.d(TAG, "..." + key + " => " + json.getString(key));
        Log.d(TAG,"");
       }

      alert = json.getString("alert").toString();
      name = json.getString("name").toString();
      tipo = json.getString("tipo").toString();

      DatosObjecto.setAlert(alert);
      DatosObjecto.setName(name);
      DatosObjecto.setTipo(tipo);

      Sdd.Serializa(DatosObjecto); //this line, I use for call the class "SerializacionDeDatos"

    } catch (JSONException e) {
      Log.d(TAG, "JSONException: " + e.getMessage());
    }
  }
}
当我收到推送时,我提取“alert”、“name”和“tipo”的值。我把它们放在一个物体里。代码:

public class ObjetoMensaje extends Activity implements Serializable{ 

private static final long serialVersionUID = 5680898935329497057L; 
private String  alert, name, tipo; 
protected String filename = "datos.dat";

public ObjetoMensaje(){}; 

public ObjetoMensaje(String alert, String name, String tipo){ 
    super(); 
    this.alert = alert;
    this.name = name;
    this.tipo = tipo; 
    }

public String getAlert(){
    return alert;
}

public void setAlert(String alert){
    this.alert = alert;
    Log.i("Set Alert", "Excitoso");
}

public String getName(){
    return name;
}

public void setName(String name){
    this.name = name;
    Log.i("Set Name", "Excitoso");
}

public String getTipo(){
    return tipo;
}

public void setTipo(String tipo){
    this.tipo = tipo;
    Log.i("Set tipo", "Excitoso");
}
}
我想序列化值“alert”、“name”和“tipo”,因此我创建了一个用于序列化的类:

public class SerializacionDeDatos extends Activity{

protected String filename = "datos.dat";
protected void Serializa(ObjetoMensaje DatosObjecto){
            FileOutputStream fos;
            try {
                fos = openFileOutput(filename, Context.MODE_PRIVATE);
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                oos.writeObject(DatosObjecto);
                oos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } 
            catch (IOException e) {
                e.printStackTrace();
            }
    }
}
调用该类时,会出现以下错误:

08-08 13:15:32.976: W/dalvikvm(8360): threadid=1: thread exiting with uncaught exception (group=0x4001c578)
08-08 13:15:33.070: E/AndroidRuntime(8360): FATAL EXCEPTION: main
08-08 13:15:33.070: E/AndroidRuntime(8360): java.lang.RuntimeException: Unable to start receiver mx.nivel9.apps.MyCustomReceiver: java.lang.NullPointerException
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:1809)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.app.ActivityThread.access$2400(ActivityThread.java:117)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:985)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.os.Looper.loop(Looper.java:130)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.app.ActivityThread.main(ActivityThread.java:3687)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at java.lang.reflect.Method.invokeNative(Native Method)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at java.lang.reflect.Method.invoke(Method.java:507)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at dalvik.system.NativeStart.main(Native Method)
08-08 13:15:33.070: E/AndroidRuntime(8360): Caused by: java.lang.NullPointerException
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:158)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at mx.nivel9.apps.SerializacionDeDatos.Serializa(SerializacionDeDatos.java:23)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at mx.nivel9.apps.MyCustomReceiver.onReceive(MyCustomReceiver.java:50)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:1798)
08-08 13:15:33.070: E/AndroidRuntime(8360):     ... 10 more

我做错了什么?

错误来自SerializacionDeDatos类中的代码行23。 您正在对一个尚未初始化的对象调用一个方法,这意味着您为一个对象创建了一个变量,但没有使用“new”操作符创建该对象,或者初始化返回null

如果“filename”无效,这一行可能会出现问题

fos = openFileOutput(filename, Context.MODE_PRIVATE);

on幸运的是,您的代码段中没有行号,因此我无法确切地说出错误的来源。

异常日志中的这些行:

08-08 13:15:33.070: E/AndroidRuntime(8360):     at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:158)
08-08 13:15:33.070: E/AndroidRuntime(8360):     at mx.nivel9.apps.SerializacionDeDatos.Serializa(SerializacionDeDatos.java:23)
告诉我们正在从中引发异常

 fos = openFileOutput(filename, Context.MODE_PRIVATE);
serializaciondadatos
类中,或者更明显的是调用
openFileOutput
,这意味着您所引用的文件可能存在基本问题(权限、存在性等)

除非您正在针对每种类型的异常执行特定的操作,否则您应该只为
(异常e)
添加一个常规的
catch
,然后在
Serializa
方法中尝试
,并打印堆栈跟踪以找出错误,如下所示:

        try {

            fos = openFileOutput(filename, Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(DatosObjecto);
            oos.close();

        } catch (Exception e) {

            e.printStackTrace();
        } 
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;

        try {

            fos = openFileOutput(filename, Context.MODE_PRIVATE);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(DatosObjecto);

        } catch (Exception e) {

            e.printStackTrace(); // NOW this should now tell us what's going wrong.

        } finally {

            try {

                oos.close();

            } catch (Exception e) {

                e.printStackTrace();
            }

            try {

                fos.close();

            } catch (Exception e) {

                e.printStackTrace();
            }
        }
进一步注意,您没有关闭
文件输出流
最佳做法是在
外部初始化它,尝试使用null
,然后在
finally
块中调用
close()
方法,如下所示:

        try {

            fos = openFileOutput(filename, Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(DatosObjecto);
            oos.close();

        } catch (Exception e) {

            e.printStackTrace();
        } 
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;

        try {

            fos = openFileOutput(filename, Context.MODE_PRIVATE);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(DatosObjecto);

        } catch (Exception e) {

            e.printStackTrace(); // NOW this should now tell us what's going wrong.

        } finally {

            try {

                oos.close();

            } catch (Exception e) {

                e.printStackTrace();
            }

            try {

                fos.close();

            } catch (Exception e) {

                e.printStackTrace();
            }
        }

更新:您在下面的评论中注意到,您收到了一个
NullPointerException
。调用
Activity.openFileOutput()
时,这是一个非常常见的问题

查看您的答案是否在以下链接中:


我做到了,你说了,抛出了很多system.err,前三个是:
W/system.err(10893):java.lang.NullPointerException W/system.err(10893):在android.content.ContextWrapper.openFileOutput(ContextWrapper.java:158)W/system.err(10893):在mx.nivel9.apps.SerializacionDeDatos.SerializacionDeDatos.Serializa(SerializacionDeDatos.java:23)
您对
活动的调用。openFileOutput
正在引发
NullPointerException
。这是一个常见的问题。检查您的答案是否在这里:或者在这里,我将不需要IOException和FileNotFoundException?这是您的电话。基本Java101。如果您需要区分如何处理
IOException
和如何处理
FileNotFoundException
,那么请区分,否则,请同时扩展
异常
,因此,它们将被捕获。您仍然必须解决根本问题:为什么此方法
openFileOutput
抛出
NullPointerException
。您应该编辑原始问题,并包括您收到的整个新堆栈跟踪。