27

Android Developers Site の次のテキスト、具体的にはFramework Topics -> Services -> Starting a Serviceの下を読んでいます。

そこには次のように記載されています。

サービスがバインドも提供しない場合、startService() で配信されるインテントは、アプリケーション コンポーネントとサービス間の通信の唯一のモードです。ただし、サービスが結果を送り返すようにする場合は、サービスを開始するクライアントがブロードキャスト用の PendingIntent を (getBroadcast() を使用して) 作成し、サービスを開始する Intent でそれをサービスに配信できます。その後、サービスはブロードキャストを使用して結果を配信できます。

これに関していくつか質問があります:

  1. Serviceこのテキストはs s の両方に適用されますIntentServiceか?
  2. Service;内からこれをどのように(コードごとに)達成する必要がありますか。その後、サービスはブロードキャストを使用して結果を配信できます。また、前述のブロードキャストはどこで結果を元のクライアント/アクティビティに配信しますか? 上書きする必要があるメソッド( などonActivityResult())などはありますか?
4

3 に答える 3

49

数ヶ月前に質問がありましたが、まだ誰かが答えを探している場合は、私が助けてくれることを願っています。

以下の例では、時間のかかる操作を実行するローカルサービスがあります。アクティビティはサービスにリクエストを送信しますが、サービスにバインドしません。リクエストとともにインテントを送信するだけです。さらに、アクティビティには、要求されたタスクでサービスが完了したときにコールバックする必要があるBroadcastReceiverの情報が含まれます。情報はPendingIntentによって渡されます。サービスはバックグラウンドスレッドでタスクを処理し、タスクが終了すると、サービスはBroadcastReceiverに応答をブロードキャストします。

1.BroadcastReceiverサブクラスを作成します。

public class DataBroadcastReceiver extends BroadcastReceiver {
   static Logger log = LoggerFactory.getLogger(DataRequestService.class);   
   @Override
   public void onReceive(Context context, Intent intent) {
      log.info(" onReceive");
   }
}

この放送受信機は、タスクが完了するとサービスから通知されます。

2.サービスを作成します

public class DataRequestService extends Service {

   private final class ServiceHandler extends Handler {
      public ServiceHandler(Looper looper) {
         super(looper);
      }

      @Override
      public void handleMessage(Message msg) {
         log.info("handleMessage");
         //... performing some time-consuming operation         
         Bundle bundle = msg.getData();
         PendingIntent receiver = bundle.getParcelable("receiver");
         // Perform the operation associated with PendingIntent
         try {            
            //you can attach data from the operation in the intent.
            Intent intent = new Intent();
            Bundle b = new Bundle();
            //b.putString("key", value);
            intent.putExtras(b);
            receiver.send(getApplicationContext(), status, intent);
         } catch (CanceledException e) {         
         e.printStackTrace();
         }         
      }
   }
   
   @Override
   public void onStart(Intent intent, int startId) {
      Bundle bundle = intent.getExtras();
      Message msg = mServiceHandler.obtainMessage();
      msg.setData(bundle);
      mServiceHandler.sendMessage(msg);
   }

さて、最も重要な部分はhandleMessage()メソッドにあります。サービスは、結果をブロードキャストレシーバーに配信するためのブロードキャスト操作を行うだけです。

3.また、Manifest.xmlにブロードキャストレシーバーとサービスを登録する必要があります

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ramps.servicetest"
    android:versionCode="1"
    android:versionName="1.0" >
   ....
       <service android:name=".service.DataRequestService" android:exported="false"/>
       <receiver android:name=".service.DataBroadcastReceiver"></receiver>
    </application>
</manifest><br>

4.最後に、アクティビティからサービスにリクエストを送信します。

Intent serviceIntent = new Intent(context, DataRequestService.class);   
   @Override
   public void onClick(View v) {
      //this is the intent that will be broadcasted by service.
      Intent broadcastReceiverIntent = new Intent(context, DataBroadcastReceiver.class);      
      //create pending intent for broadcasting the DataBroadcastReceiver
      PendingIntent pi = PendingIntent.getBroadcast(context, 0, broadcastReceiverIntent, 0);      
      Bundle bundle = new Bundle();            
      bundle.putParcelable("receiver", pi);
      //we want to start our service (for handling our time-consuming operation)
      Intent serviceIntent = new Intent(context, DataRequestService.class);
      serviceIntent.putExtras(bundle);
      context.startService(serviceIntent);
   }



5.元のクライアント/アクティビティに応答を提供します

あなたはあなたのすべての活動が拡張される抽象的な活動を持つことができます。このabstrctアクティビティは、ブロードキャストレシーバーの応答リスナーとして自動的に登録/登録解除できます。ここには実際には多くのオプションはありませんが、アクティビティへの静的参照を保持する場合は、アクティビティが破棄されたときに参照を削除する必要があることが重要です。

よろしく、
ランプ

于 2011-11-06T18:59:01.057 に答える