从Intent检索Extras时出现NullPointerException

时间:2016-02-11 04:39:33

标签: android android-intent service nullpointerexception

我正在为我的Android App构建Location_Service。我有一个服务说,T_Service从电话启动开始,并检查其onStartCommand()中的几个条件以启动我的Location_Service。我想将这些条件作为意图从与T_Service相关联的广播接收器发送。

我执行以下操作:

Broadcast Receiver

中  
 public class T_BroadcastReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                Intent i = new Intent(context,T_Service.class);
                i.putExtra("PARENT_ACTIVITY_NAME","com.example.helloworld");
                context.startService(i);
            }
        }

T_Service课程中:

 
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
     Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
        }

当我的代码到达上述点时,我得到一个NullPointerException,该点试图打印与Intent中设置的键相关联的值。

请告诉我如何处理在电话启动时启动的T_Service等服务意图添加额外内容的情况。

异常的堆栈跟踪:

FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start service org.abc.def.services.TService@41593b58 with null: java.lang.NullPointerException
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2387)
            at android.app.ActivityThread.access$1900(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1221)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4511)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at org.abc.def.services.TrackerService.onStartCommand(TrackerService.java:140)
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2370)
            at android.app.ActivityThread.access$1900(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1221)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4511)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
            at dalvik.system.NativeStart.main(Native Method)

5 个答案:

答案 0 :(得分:1)

请阅读onStartService的javadoc。它表示intent参数可以为null,因此在调用其上的方法之前,应始终检查它是否为null。

我的经验是,即使你认为 IntentSevice永远不会在那里收到空值,实际上在极少数情况下仍然可能。因此,即使您认为它不会发生,您仍应将其检查为空。

答案 1 :(得分:1)

从文档(onStartCommand):

  

参数" intent":提供给startService(Intent)的Intent,如给定的。    如果服务在其进程消失后重新启动,则可能为null   离开了,之前它还没有返回任何东西   START_STICKY_COMPATIBILITY。

如果你在手机启动上运行,很可能会因为启动它的过程已经消失而导致意图失效。

要获得在public static readonly DependencyProperty SessionCollectionProperty = DependencyProperty.Register( "SessionCollection" , typeof(Session) , typeof(CustomSession) , new PropertyMetadata(new Session()) ); public Session SessionCollection { get { return (Session)GetValue(SessionCollectionProperty); } set { SetValue(SessionCollectionProperty, value); } } 方法中返回START_REDELIVER_INTENT所需的相同意图,如下所示:

onStartCommand

只要服务重新启动(例如在电话启动时),返回@Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME")); return Service.START_REDELIVER_INTENT; } 将使intent参数再次传递给START_REDELIVER_INTENT方法。

有关详细信息,请查看documentation

  

<强> START_REDELIVER_INTENT

     

从onStartCommand(Intent,int,int)返回的常量:如果是这样   服务的进程在启动时被终止(从...返回后)   onStartCommand(Intent,int,int)),然后它将被安排为a   重新启动,最后一次交付的Intent再次通过它重新发送给它   onStartCommand(Intent,int,int)

答案 2 :(得分:0)

请在访问前检查您的意图和额外字符串。可能是空的

if(intent.getExtras()!=null && intent.hasExtra("PARENT_ACTIVITY_NAME")){
 Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}

要传递意图,请参阅较旧的主题。

Pass data from Activity to Service using an Intent

答案 3 :(得分:0)

根据Intent API文档,您必须在附加名称中包含包名称。

  

public Intent putExtra(String name,String value)

     

在API级别1中添加   将扩展数据添加到intent。 名称必须包含包前缀,例如app com.android.contacts将使用“com.android.contacts.ShowAll”之类的名称。

     

参数   name包含前缀的额外数据的名称。   value String数据值。   返回   返回相同的Intent对象,用于将多个调用链接到单个语句中。   也可以看看   putExtras(意向)   removeExtra(字符串)   getStringExtra(字符串)

答案 4 :(得分:0)

替换此

 @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
   Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
    }

用这个

@Override
  public int onStartCommand(Intent intent, int flags, int startId) {
     super.onStartCommand(intent, flags, startId);

     Bundle b = getIntent().getExtras();
      if (b != null){
     Log.d("APP","The intent has parent activity :"+b.getString("PARENT_ACTIVITY_NAME")); }