2015-07-08 2 views
2

My alarmManager находится в MainActivity, который запускается каждые 30 секунд для класса MyReceiver, а затем из него. Я запускаю класс IntentService GetLLRD. После этого я отправляю запрос с onHandleIntent на сервер, после которого я получаю ответ. Теперь я хочу добиться следующего, каждый раз, когда alarmManager запускается в MainActivity, я хочу передать намерение от ответа от сервера в классе GetLLRD классу Map.'java.lang.String android.content.Context.getPackageName()' на ссылке нулевого объекта

Я пробовал это дважды с кодом намерения в классе 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); 

       } 
     }  
    } 

Edit:

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); 

     } 

    } 

}; 
+0

Возможный дубликат [Попытка вызвать виртуальный метод 'java.lang.String android.content.Context.getPackageName() для ссылки на нулевой объект) (http://stackoverflow.com/questions/31265067/attempt-to -invoke-virtual-method-java-lang-string-android-content-context-getpa) – Selvin

+0

@Selvin: Нет, это не то же самое, что и другое. – MrPencil

ответ

3

Ваша архитектура несовершенна. IntentService создается, когда вы звоните startService(). Затем в службе вызывается onCreate() и onHandleIntent(). По завершении onHandleIntent(), если нет других ожидающих намерений для обработки, Служба останавливается.

Вы делаете этот призыв в MainActivityперед тем вы звоните startService():

getLRLD.received_MainActvity_Context(context); 

Вы не показать, как вы устанавливаете ссылочную переменную getLRLD, но это не будет работать. Служба фактически не создается до тех пор, пока вы не назовете startService().

Вы пытаетесь установить канал связи между Сервисом и Управлением. Однако вы используете IntentService, который является непостоянным. Он создается по мере необходимости, и когда ему нечего делать, он уходит.Поэтому вы не можете передавать ссылку на Службу на Activity, и вы также не должны передавать ссылку на Activity to the Service.

Лучший способ достичь связи между службой и деятельности является одним из следующих:

  1. служба посылает широковещательный Intent с данными. Активность может регистрировать BroadcastRecevier, чтобы слушать это.

  2. активности создает PendingIntent, содержащую необходимые меры, компонентный, и т.д., и передает его службу как «экстра» в Intent он использует при вызове startService(). Служба возвращает send() по этому адресу PendingIntent, чтобы вернуть данные в Работу.

В обоих случаях Службе не нужно ничего знать о деятельности, а Деятельности не требуется ссылка на Службу.

EDIT: Добавьте код, чтобы начать активность

Если вы хотите начать активность, вы можете сделать это в 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. Если действие уже запущено, вы можете получить «дополнительные» из Intent, переопределив onNewIntent() в Управлении.

Если вы используете этот подход, вам не нужно использовать трансляцию Intent для отправки данных из Сервиса в Activity.

+0

Я устанавливаю ссылочную переменную следующим образом: GetLLRD getLRLD = new GetLLRD(); 'Я попытался установить эту строку' getLRLD.received_MainActvity_Context (контекст); 'after' startService (intent)', но, как вы сказали, я получаю та же ошибка. Также в методе 'onHandleIntent' я получаю PendingIntent от alarmManager каждые 30 секунд, но когда я пытаюсь передать результат с сервера на активность Map, возникает ошибка, и alarmManager перестает запускать PendingIntent. который onCreate вы имеете в виду здесь 'Тогда onCreate() и onHandleIntent() вызывается в службе. '? – MrPencil

+0

Не могли бы вы также добавить код, чтобы посмотреть, как выглядит первый подход с BroadcastRecevier? – MrPencil

+0

Вы абсолютно не можете создавать компоненты Android (например, 'Активность',' Сервис', 'BroadcastReceiver' и т. Д.), Используя ключевое слово' new'. Только инфраструктура Android может создавать эти компоненты. Кроме того, 'onCreate(), на который я ссылаюсь, находится в' Сервис'. –

Смежные вопросы