2

나는 그 안에 ResultReceiver가있는 BroadcastReceiver를 사용하는 방법에 대해 질문합니다.BroadcastReceiver와 ResultReceiver 및 평생

"A BroadcastReceiver가 10 초 내에 실행을 완료하지 못했습니다."라는 사실을 알고 있습니다. ANR이 있습니다.

나는 Manifest에 선언 된 Intent에 응답하는 응용 프로그램을 가지고 있습니다.

public class MyReceiver extends BroadcastReceiver { 

    private Context context = null; 
    private MyResultReceiver myResultReceiver = null; 

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

     this.context = context; 
     myResultReceiver = new MyResultReceiver(new Handler()); 

     Intent i = new Intent(); 
     i.setClass(context, MyService.class); 
     i.putExtra(Constants.EXTRA_RESULT_RECEIVER, myResultReceiver); 
     context.startService(i); 
    } 

    public class MyResultReceiver extends ResultReceiver { 

     public MyResultReceiver(Handler handler) { 
      super(handler); 
     } 

     @Override 
     protected void onReceiveResult(int resultCode, Bundle resultData) { 
      if (resultCode == 42) { 
       // Something 
      } else { 
       // Something else 
      } 
     } 
    } 
} 

내 서비스는 다음과 같습니다 :

public class MyService extends Service { 

    private Context context = null; 
    private ResultReceiver resultReceiver = null; 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     this.context = this; 
     resultReceiver = intent.getParcelableExtra(Constants.EXTRA_RESULT_RECEIVER); 
     MyTask myTask = new MyTask(); 
     myTask.execute(); 
     return super.onStartCommand(intent, flags, startId); 
    } 

    public class MyTask extends AsyncTask<Void, Void, Boolean> { 

     @Override 
     protected Boolean doInBackground(Void... params) { 
      // Network operation 
      return status; 
     } 

     @Override 
     protected void onPostExecute(final Boolean status) { 
      Bundle bundle = new Bundle(); 
      if (status == true) { 
       if (resultReceiver != null) { 
        resultReceiver.send(42, null); 
       } 
      } else { 
       if (resultReceiver != null) { 
        resultReceiver.send(-1, null); 
       } 
      } 
     } 
    } 
} 

내 질문은, 내가 확인 resultReceiver이 여전히 존재한다는 생각은 일부 네트워크 작업을해야하기 때문에 그것은 서비스을 (를) 브로드 캐스트 리시버 시작된다 네트워크 작업이 10 초보다 길면 어떻게해야할까요?

답변

0

가 여기에 SDK에서 relevant documentation의 :

이 브로드 캐스트 리시버가 태그를 통해 출시 된 경우, 객체가이 기능에서 돌아온 후 더 이상 살아 없습니다. 이 은 결과를 비동기로 반환하는 작업을 수행하면 안됩니다. 특히 서비스와 상호 작용하는 경우 bindService (Intent, ServiceConnection, int) 대신 startService (Intent)를 사용해야합니다. 이 이미 실행중인 서비스와 상호 작용하려는 경우 peekService (Context, Intent)를 사용할 수 있습니다.

registerReceiver (BroadcastReceiver, IntentFilter) 및 응용 프로그램 매니페스트에 사용 된 인 텐트 필터는 이 아닌 것으로 보장되지 않습니다. 적합한 수신자를 찾는 방법에 대한 운영 체제에 대한 힌트입니다. 보낸 사람은 필터 해상도를 무시하고 특정받는 사람에게 배달을 강제 실행할 수 있습니다. 이러한 이유 때문에 onReceive() 구현은 알려진 동작에만 응답해야합니다 (예 : ). 수신 할 수있는 예상치 못한 인 텐트는 무시됩니다.

결론은 : 당신이 서비스를 시작하면

  1. , startService(Intent)를 사용합니다.
  2. onReceive에서 장기간 실행되는 응용 프로그램을 실행하지 마십시오.
  3. AsyncTasks가 손상 될 수 있으므로 서비스를 사용하는 것이 가장 좋습니다. 서비스 내부에서 AsyncTask를 사용하고 있다면 괜찮을 것입니다.
+1

"결론"- 1. OP * IS *는 'startService (...)'를 사용합니다. 2. 영업 이익은 이것을 압니다. 따라서 질문입니다. 3. OP * IS *는 '서비스'를 사용합니다. 시피'Service '에서'AsyncTask'를 사용하는 것은 무의미합니다 (AsyncTask는 UI와 상호 작용하도록 설계되었습니다). 그렇더라도'AsyncTask'는'Service'에서 파괴 될 확률이 훨씬 적습니다. 활동 중. – Squonk

+0

@Squonk이 말했듯이이 대답은 나를 돕지 않습니다. 하지만 노력해 줘서 고마워. – ldemay