【问题标题】:'java.lang.String android.content.Context.getPackageName()' on a null object reference空对象引用上的“java.lang.String android.content.Context.getPackageName()”
【发布时间】:2015-07-08 11:36:57
【问题描述】:

我的 alarmManager 在 MainActivity 中,它每 30 秒触发一次 MyReceiver 类,然后我从它开始 GetLLRD IntentService 类。此后,我从onHandleIntent 方法向服务器发送一个请求,然后我得到一个响应。现在我想实现以下目标,每次在MainActivity 中触发alarmManager 时,我都想将GetLLRD 类中来自服务器的响应中的Intent 传递给Map 类。

我已经使用 GetLLRD 类中的意图代码尝试了两次,这部分 Intent intent1 = new Intent(this, Map.class); 我在 Map 活动中只收到了一次意图。有了这个Intent intent1 = new Intent(mContext, Map.class);,应用程序崩溃了,我在下面收到了这个错误。我怎样才能达到我的目的?

错误:

07-08 13:04:33.482: E/AndroidRuntime(16838): FATAL EXCEPTION: IntentService[IntentService]
07-08 13:04:33.482: E/AndroidRuntime(16838): Process: com.bustracker, PID: 16838
07-08 13:04:33.482: E/AndroidRuntime(16838): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
07-08 13:04:33.482: E/AndroidRuntime(16838):    at android.content.ComponentName.<init>(ComponentName.java:77)
07-08 13:04:33.482: E/AndroidRuntime(16838):    at android.content.Intent.<init>(Intent.java:4570)
07-08 13:04:33.482: E/AndroidRuntime(16838):    at com.bustracker.GetLLRD.onHandleIntent(GetLLRD.java:98)
07-08 13:04:33.482: E/AndroidRuntime(16838):    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
07-08 13:04:33.482: E/AndroidRuntime(16838):    at android.os.Handler.dispatchMessage(Handler.java:102)
07-08 13:04:33.482: E/AndroidRuntime(16838):    at android.os.Looper.loop(Looper.java:145)
07-08 13:04:33.482: E/AndroidRuntime(16838):    at android.os.HandlerThread.run(HandlerThread.java:61)

MainActivity:

public class MainActivity extends ActionBarActivity{
        Context context;

                    getLRLD.received_MainActvity_Context(context);
                    Intent intent = new Intent(MainActivity.this,
                            IntentReceiver.class);
                    intent.putExtra("json_data", json);
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(
                            getApplicationContext(), 1, intent,
                            PendingIntent.FLAG_UPDATE_CURRENT);
                    AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                    Calendar cal = Calendar.getInstance();
                    alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                            System.currentTimeMillis(), 30 * 1000,
                            pendingIntent);
                  startService(intent);

 }

MyReceiver 类:

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            String action = intent.getStringExtra("json_data");

            if (!action.isEmpty()) {

                startService(context, action);

            }
        } catch (Exception e) {
        }
    }

    public void startService(Context context, String action) {
        Intent inetent = new Intent(context, GetLLRD.class);
        inetent.putExtra("json_data", action);
        context.startService(inetent);
    }

}

GetLLRD 类:

public class GetLLRD extends IntentService {
    Context mContext;

    public GetLLRD() {
        super("IntentService");

    }
    public void received_MainActvity_Context(Context context){
        this.mContext = context;


    }

    @Override
    protected void onHandleIntent(Intent intent) {

        String jSONString = intent.getStringExtra("json_data");

        if (jSONString != null) {
                 //So if I try it in this way I am just receiving the data intent just once in the Map activity.
                             Intent intent1 = new Intent(this, Map.class);
                             intent1.putExtra("list_data", data);
                             intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                             startActivity(intent1);

               //When I do it in this way I am getting the error above:
                             Intent intent1 = new Intent(mContext, Map.class);
                             intent1.putExtra("list_data", data);
                             intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                             mContext.startActivity(intent1);

        }
    }
 }

地图活动:

public class Map extends ActionBarActivity{

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            Intent intent = getIntent();        
            @SuppressWarnings("unchecked")
             ArrayList<ItemDTO> list =(ArrayList<ItemDTO>) intent.getSerializableExtra("list_data");
                for (ItemDTO itemDTO : list) {
                    double latitude = itemDTO.getLatitude();
                    double longitude = itemDTO.getLongitude();
                    int route = itemDTO.getRoute();
                    String direction = itemDTO.getDirection();
                    System.out.println("test from Map activity:  " + latitude + ", " + longitude
                            + ", " + ", " + route + ", " + direction);

                }
        }       
    }

编辑:

GetLLRD IntentService 类:

            if (data != null && !data.isEmpty()) {
                                            Intent localIntent = new Intent(
                                Constants.BROADCAST_ACTION).putExtra(
                                "data_list", data);
                        LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
            } 

地图活动内部:

onCraete(Bundle savedInstanceState){
        IntentFilter data_filter = new IntentFilter();
        data_filter.addAction(Constants.BROADCAST_ACTION);
        registerReceiver(data_receiver, data_filter);
}


final BroadcastReceiver data_receiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        @SuppressWarnings("unchecked")
        ArrayList<ItemDTO> list = (ArrayList<ItemDTO>) intent
                .getSerializableExtra("list_data");
        for (ItemDTO itemDTO : list) {
            double latitude = itemDTO.getLatitude();
            double longitude = itemDTO.getLongitude();
            int route = itemDTO.getRoute();
            String direction = itemDTO.getDirection();
            System.out.println("test from Apple activity:  " + latitude
                    + ", " + longitude + ", " + ", " + route + ", "
                    + direction);

        }

    }

};

【问题讨论】:

  • @Selvin: 不一样是不一样的。

标签: android android-intent arraylist


【解决方案1】:

您的架构存在缺陷。 IntentService 是在您调用 startService() 时创建的。然后在服务中调用onCreate()onHandleIntent()onHandleIntent() 完成后,如果没有其他待处理的 Intent 需要处理,则服务停止。

你在MainActivity打这个电话你打电话给startService()之前:

getLRLD.received_MainActvity_Context(context);

您没有展示如何设置引用变量getLRLD,但这不会起作用。直到您调用 startService(),该服务才真正创建。

您正在尝试在服务和活动之间建立通信通道。但是,您使用的是非持久服务IntentService。它是根据需要创建的,当它无事可做时,它就会消失。因此,您不能将对 Service 的引用传递给 Activity,也不应该将对 Activity 的引用传递给 Service。

在 Service 和 Activity 之间实现通信的最佳方式是以下之一:

  1. 服务发送带有数据的广播Intent。 Activity 可以注册一个 BroadcastRecevier 来监听这个。

  2. Activity 创建一个 PendingIntent 包含必要的 ACTION、COMPONENT 等,并将其作为调用 startService() 时使用的 Intent 中的“额外”传递给服务。 Service 会在该 PendingIntent 上调用 send(),以便将数据返回给 Activity。

在这两种情况下,Service 都不需要知道关于 Activity 的任何信息,并且 Activity 也不需要对 Service 的引用。

编辑:添加代码以启动 Activity

如果你想启动一个Activity,你可以在Service.onHandleIntent()

Intent intent1 = new Intent(this, Map.class);
intent1.putExtra("list_data", data);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
              Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent1);

使用Intent.FLAG_ACTIVITY_SINGLE_TOP 将阻止Android 启动新的Activity 实例,如果已经有一个Activity 实例正在运行。如果 Activity 已经在运行,您可以通过覆盖 Activity 中的 onNewIntent()Intent 获取“附加”。

如果您使用这种方法,则不需要使用广播 Intent 将数据从 Service 发送到 Activity。

【讨论】:

  • 我将引用变量设置为以下GetLLRD getLRLD = new GetLLRD(); 我试图在startService(intent) 之后设置这一行`getLRLD.received_MainActvity_Context(context);` 但正如你所说我得到了同样的错误.同样在onHandleIntent 方法中,我每30 秒从alarmManager 接收PendingIntent,但是当我尝试将结果从服务器传递到Map 活动时,会发生错误并且alarmManager 停止触发PendingIntent。你在这里指的是哪个 onCreate Then onCreate() and onHandleIntent() is called in the Service.
  • 能否请您也添加一些代码,看看第一个使用 BroadcastRecevier 的方法是什么样子的?
  • 您绝对不能使用关键字 new 创建 Android 组件(如 ActivityServiceBroadcastReceiver 等)。只有 Android 框架可以实例化这些组件。另外,我指的onCreate()Service中。
  • 使用广播Intent的示例代码见developer.android.com/training/run-background-service/…
  • 是的,它可以使用 FLAG_ACTIVITY_SINGLE_TOP)onNewIntent() 方法。感谢您的支持。
猜你喜欢
  • 2018-10-29
  • 1970-01-01
  • 2015-04-15
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
相关资源
最近更新 更多