4

이 질문은 이전에 묻지 만 모든 답변을 살펴본 결과 문제를 해결할 수 없었습니다.IntentService에서 OnHandleIntent()가 호출되지 않았습니다.

BroadcastReceiver가 시작되면 IntentService onHandleIntent()가 호출되지 않습니다. 이상하게도 생성자가 실행됩니다 (Log 출력에서 ​​볼 수 있듯이). 이 내 코드입니다.

이 NoLiSeA.class가 가 (이 클래스는 내 서비스를 시작하는 브로드 캐스트 리시버를 포함)

public void toProcess(StatusBarNotification sbn) { 
    LocalBroadcastManager.getInstance(this).registerReceiver(notificationForwarder, new IntentFilter("to_forward")); 
    Intent intent = new Intent("to_forward"); 
    intent.putExtra("sbn", sbn); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 
    Log.i("NoLiSe.TAG", "toProcess"); 
} 

private BroadcastReceiver notificationForwarder = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
      Log.i("NoLiSe.TAG", "BroadCastReceiver.onReceive"); 
      Intent i = new Intent(context, CoreTwoA.class); 
      i.putExtras(intent); 
      startService(i); 
     } 
    } 
}; 

CoreTwoA.class는 는 (이것은 IntentService입니다 onHandleIntent()이다 콘솔에 로그 텍스트가 없으므로 불려 가지 않습니다.)

public class CoreTwoA extends IntentService { 

    private TextToSpeech mtts; 

    public CoreTwoA() { 
     super("TheCoreWorker"); 
     Log.d("source", "exception", new Exception()); 
     Log.i("CoreTwoA.TAG", "Constructor"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     Log.i("CoreTwoA.TAG", "onHandleIntent"); 

    } 
} 

AndroidManifest.xml에

<service 
     android:name=".CoreTwoA" 
     android:label="@string/service_name" 
     android:exported="false"> 
    </service> 

UPDATE

그래서 아래의 논의를 기반으로, 나는 브로드 캐스트 리시버에서 다음 코드 줄에 문제를 좁힐 수 있었다 :

i.putExtra("sbn", sbn) 

만약 그것을 제거, 즉 intentService 내 onHandleIntent() 메서드가 실행되지 않습니다 즉, 의도에 엑스트라를 추가합니다.

이 포함 된 경우, onHandleIntent()가 실행되지 않는 StatusBarNotification 객체를 전달 왜 내 IntentService의 생성자에서)에 Log.d (가 로그 캣에

06-10 19:40:35.355 25094-25094/com.dezainapps.myapp D/source: exception 
                     java.lang.Exception 
                      at com.dezainapps.myapp.CoreTwoA.<init>(CoreTwoA.java:20) 
                      at java.lang.Class.newInstance(Native Method) 
                      at android.app.ActivityThread.handleCreateService(ActivityThread.java:2859) 
                      at android.app.ActivityThread.-wrap4(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:5417) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
06-10 19:40:35.355 25094-25094/com.dezainapps.myapp I/CoreTwoA.TAG: Constructor 

어떤 아이디어를 기록 다음 , Intellent를 통해 Parcelable을 구현하는 Intent가 작동하지 않습니까? 이상하게도 내 인벤토리 (코드 참조)를 통해 내 toProcess() 메소드에서 동일한 StatusBarNotfication sbn 객체가 제대로 작동하지 않습니다.

+2

''notificationForwarder'가 실제로 실행되는 로그를 확인 했습니까? 아마도 수신기를 등록하는 것을 잊었을 것입니다. 'onStartCommand'가 실행되지 않았을 때 서비스가 시작되지 않거나 그 반대가됩니다. 생성자에서'Log.d ("source", "", new Exception())'를 실행하여 생성자를 생성하는 방법을 찾아 낼 수도 있습니다. – zapl

+0

@zapl 그래서 생성자에 Log.d()를 추가하고 위에 게시 된 예외를 수신합니다. 그러나 나는 예외를 이해하지 못한다. 도움이 되시면 감사하겠습니다. 좋은 제안 주셔서 감사합니다. – REG1

+0

@AADTechnical 브로드 캐스트를 보내는 방법을 추가했습니다. – REG1

답변

0

context.startService (intent);를 사용해 보셨습니까?

이런 브로드 캐스트 리시버를 사용할 때 참조 할 컨텍스트가 없다면 onRecieve 메서드에 전달 된 컨텍스트를 사용해야 할 것입니다.

+0

context.startService (인 텐트)로 변경했습니다. 그러나 그것은 아무것도 바뀌지 않았습니다. – REG1

0

사용이 :

private BroadcastReceiver notificationForwarder = new BroadcastReceiver() { 
@Override 
public void onReceive(Context context, Intent intent) { 
     Log.i("NoLiSe.TAG", "BroadCastReceiver.onReceive"); 
     Intent i = new Intent(context, CoreTwoA.class); 
     i.putExtra("intent",intent); 
     context.startService(i); 
    } 
} 

}; 코드 아래

+0

돌을 아무렇지도 않게 남기지 않기 위해 나는 이것을 시도했지만 아무 것도 변하지 않았습니다. – REG1

0

사용 : 당신은 잘못 내가 제거하고 putExtra 통해 StatusBarNotification 객체를 보내는 다른 방법을 추가 i.putExtras(intent);를 사용하는

private BroadcastReceiver notificationForwarder = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      Log.e("NoLiSe.TAG", "BroadCastReceiver.onReceive"); 
      Intent i = new Intent(context, CoreTwoA.class); 
      i.putExtra("sbn",intent.getParcelableExtra("sbn")); 
      startService(i); 
     } 
    }; 

.

는이 코드를 테스트하고 나는 OP와 같은 문제가 있었다 onHandleIntent

+0

그래, 코드를 복사하여 붙여 넣으면 onHandleIntent가 호출되어 작동합니다. 그러나 지금은 그 의도가 없다. StatusBarNotification sbn을 추가로 보내려면 어떻게해야합니까? 나는'StatusBarNotfication sbn = intent.getParcelableExtra ("sbn");을 추가하려고 시도했다. i.putExtra ("sbn", sbn); ' 을 코드에 추가했지만 이상한 정도로 onHandleIntent가 호출되지 않으므로 이전 문제로 다시 돌아갑니다. 아이디어가 있으십니까? 최소한 내 IntentService가 어느 정도 작동하는지 확인해 주셔서 감사합니다. – REG1

+0

@ REG1 이것은 우리가해야 할 일이다.'i.putExtra ("sbn", intent.getParcelableExtra ("sbn"));'여기서 우리는 두 번째 매개 변수를 Parcelable로 취하는 putExtra API를 사용한다. 'putExtra (String name, Parcelable value)'다시 시도해 보니 onHandleIntent가 – AADProgramming

+0

으로 불리는 것을 볼 수 있습니다. 그래서 저는 여러분이 말한 것과 똑같이하고 있습니다 :'i.putExtra ("sbn", intent.getParcelableExtra ("sbn"); 여기서 'sbn'은 StatusBarNotification 유형이지만, onHandleIntent()는 호출되지 않습니다. 또한 toProcess() 메소드에서 직접 서비스를 시작하고 StatusBarNotfication sbn 매개 변수를 내 의도대로 추가하려고했습니다. – REG1

1

전화 않습니다.

문제

내가 IntentService 시작 Intent을 통해 거대한 ArrayList (약 4000 Parcelable 요소) 통과 된 것으로 밝혀졌다. 그것은 고객의 장치에서 '자동으로'실패로 진단하기가 극히 어려웠으므로 ACRA 오류 보고서가 없습니다.

어쨌든, 나는 문제를 해결하기 위해 기본적으로 ArrayList을 저장하고 Intent를 통해 전달하려고 시도하지 않고 ArrayList를 설정/가져 오는 정적 요소를 저장했습니다.

더 많은 조사에서 (다른 장치를 테스트 한 결과) TransactionTooLargeException이 발견되었습니다. More discussion on that here.

테스트 코드를

를 당신이 훨씬 작은 뭔가에 4000 값을 변경 작업을 확인하려면 : 사람이 복제하고 싶은 경우

여기 내 테스트 코드입니다. 내가 말처럼

ArrayList<ParcelableNameValuePair> testArrayList = new ArrayList<>(); 
for (int i = 0; i < 4000; i++) { 
    testArrayList.add(new ParcelableNameValuePair("name" + i, "value" + i)); 
} 
TestIntentService.startAction(AdminHomeActivity.this, testArrayList); 

TestIntentService.java

public class TestIntentService extends IntentService { 

    private static final String LOG_TAG = TestIntentService.class.getSimpleName(); 

    private static final String TEST_ACTION = "com.example.action.FOO"; 

    private static final String EXTRA_PARAM1 = "com.example.extra.PARAM1"; 
    private static final String EXTRA_PARAM2 = "com.example.extra.PARAM2"; 

    public TestIntentService() { 
     super("TestIntentService"); 
    } 

    public static void startAction(Context context, ArrayList<ParcelableNameValuePair> testArrayList) { 

     Log.d(LOG_TAG, "1. startAction()"); 
     Utilities.makeToast(context, "1. startAction()"); 

     try { 
      int arrayListSize = (testArrayList == null) ? -1 : testArrayList.size(); 
      Log.d(LOG_TAG, "2. arrayListSize: " + arrayListSize); 
      Utilities.makeToast(context, "2. arrayListSize: " + arrayListSize); 

      Intent intent = new Intent(context, TestIntentService.class); 
      intent.setAction(TEST_ACTION); 
      //intent.putExtra(EXTRA_PARAM1, testArrayList); 
      intent.putParcelableArrayListExtra(EXTRA_PARAM2, testArrayList); 

      /** 
      * This line should result in a call to onHandleIntent() but, if we're sending a huge ArrayList, it doesn't... 
      */ 
      context.startService(intent); 
     } 
     catch(Exception e) { 
      Log.e(LOG_TAG, "Exception starting service", e); 
      Utilities.makeToast(context, "Exception starting service: " + e); 
     } 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     Log.d(LOG_TAG, "3. onHandleIntent()"); 
     Utilities.makeToast(getApplicationContext(), "3. onHandleIntent()"); 

     try { 
      if (intent != null) { 
       final String action = intent.getAction(); 
       if (TEST_ACTION.equals(action)) { 

        ArrayList<ParcelableNameValuePair> testArrayList = intent.getParcelableArrayListExtra(EXTRA_PARAM1); 
        int testArrayListSize = (testArrayList == null) ? -1 : testArrayList.size(); 
        Log.d(LOG_TAG, "4. testArrayListSize: " + testArrayListSize); 
        Utilities.makeToast(getApplicationContext(), "4. testArrayListSize: " + testArrayListSize); 

        ArrayList<ParcelableNameValuePair> testArrayList2 = intent.getParcelableArrayListExtra(EXTRA_PARAM2); 
        int testArrayList2Size = (testArrayList2 == null) ? -1 : testArrayList2.size(); 
        Log.d(LOG_TAG, "5. testArrayList2Size: " + testArrayList2Size); 
        Utilities.makeToast(getApplicationContext(), "5. testArrayList2Size: " + testArrayList2Size); 

       } 
      } 
     } 
     catch(Exception e) { 
      Log.e(LOG_TAG, "Exception handling service intent", e); 
      Utilities.makeToast(getApplicationContext(), "Exception handling service intent: " + e); 
     } 
    } 

} 

ParcelableNameValuePair.java

public class ParcelableNameValuePair implements Parcelable { 

    private String name, value; 

    public ParcelableNameValuePair(String name, String value) { 
     this.name = name; 
     this.value = value; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getValue() { 
     return value; 
    } 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel out, int flags) { 
     out.writeString(name); 
     out.writeString(value); 
    } 

    public static final Parcelable.Creator<ParcelableNameValuePair> CREATOR = new Parcelable.Creator<ParcelableNameValuePair>() { 
     public ParcelableNameValuePair createFromParcel(Parcel in) { 
      return new ParcelableNameValuePair(in); 
     } 

     public ParcelableNameValuePair[] newArray(int size) { 
      return new ParcelableNameValuePair[size]; 
     } 
    }; 

    private ParcelableNameValuePair(Parcel in) { 
     name = in.readString(); 
     value = in.readString(); 
    } 

} 

, 나는이 문제를 해결하기 위해 신속하고 더러운 솔루션을 사용했다. 더 나은 해결책은 파일 시스템에 ArrayList을 작성한 다음 해당 파일 (예 : 파일 이름/경로)에 대한 참조를 IntentService에 대한 의도를 통해 전달한 다음 IntentService이 파일 내용을 검색하고 변환하도록하는 것입니다. 그것은 ArrayList으로 되돌아갑니다.

IntentService이 파일을 함께 할 때, 그것을 삭제하거나 공급 된 동일한 파일 참조를 다시 통과가 만든 파일을 (삭제 로컬 방송을 통해 응용 프로그램에 다시 지시를 전달해야 하나 그것).

관련 문제