web-dev-qa-db-ja.com

AndroidでResultReceiverを使用する

基本的に、IntentServiceからActivityへのコールバックを確立したいと思います。私の質問は、ここで回答した質問とよく似ています。

Restful APIサービス

ただし、応答コードでは、アクティビティコードはResultReceiverを実装していると見なされます。何かが足りない限り、ResultReceiverは実際にはクラスなので、この実装を実行できません。

そのため、本質的には、ResultReceiverをそのサービスに接続するための正しい方法を尋ねています。これに関して、HandlerおよびResultReceiverの概念と混同されます。実用的なサンプルコードをいただければ幸いです。

59
Bill Eisenhauer
  1. ResultReceiverから拡張されたカスタムresultreceiverクラスを作成する必要があります

  2. その後、アクティビティにresultreceiverインターフェースを実装します

  3. カスタムresultreceiverオブジェクトをintentServiceに渡し、intentserviceでレシーバーオブジェクトをフェッチし、receiver.send()関数を呼び出して、Bundleオブジェクトの呼び出しアクティビティに何かを送信します。

    ここにcustomResultReceiverクラスがあります:

     public class MyResultReceiver extends ResultReceiver {
    
        private Receiver mReceiver;
    
        public MyResultReceiver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }
    
        public interface Receiver {
            public void onReceiveResult(int resultCode, Bundle resultData);
    
        }
    
        public void setReceiver(Receiver receiver) {
            mReceiver = receiver;
        }
    
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
    
            if (mReceiver != null) {
                mReceiver.onReceiveResult(resultCode, resultData);
            }
        }
    
    }
    

アクティビティにMyresultreceiver.receiverインターフェースを実装し、クラス変数を作成します

Public MyResultReceiver mReceiver;

onCreateでこの変数を初期化します。

mReceiver = new MyResultReceiver(new Handler());

mReceiver.setReceiver(this);

このmReceiverをintentServiceに渡します:

intent.putExtra("receiverTag", mReceiver);

次のようなIntentServiceで取得します。

ResultReceiver rec = intent.getParcelableExtra("receiverTag");

次のようにrecを使用してアクティビティに何かを送信します。

Bundle b=new Bundle();
rec.send(0, b);

これは、アクティビティのonReceiveResultで受信されます。完全なコードは、次の場所で表示できます。 IntentService:アクティビティへのデータの提供

編集:onResumeでsetReceiver(this)を呼び出し、onPause()でsetReceiver(null)を呼び出してリークを回避する必要があります。

116
SohailAziz

サブクラス化によってメソッドをオーバーライドします。それを行うためのインターフェースである必要はありません。

例えば:

intent.putExtra(StockService.REQUEST_RECEIVER_EXTRA, new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        if (resultCode == StockService.RESULT_ID_QUOTE) {
            ...
        }
    }
});

ResultReceiverの使用方法を示す簡単な例を作成しました。

MainActivity

public class MainActivity extends AppCompatActivity {

    private final static String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent serviceIntent = new Intent(this, MyService.class);
        serviceIntent.putExtra("logName", "MAIN_ACTIVITY");
        serviceIntent.putExtra(MyService.BUNDLED_LISTENER, new ResultReceiver(new Handler()) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                super.onReceiveResult(resultCode, resultData);

                if (resultCode == Activity.RESULT_OK) {
                    String val = resultData.getString("value");
                    Log.i(TAG, "++++++++++++RESULT_OK+++++++++++ [" + val + "]");
                } else {
                    Log.i(TAG, "+++++++++++++RESULT_NOT_OK++++++++++++");
                }
            }
        });
        startService(serviceIntent);
    }
}

MyService

public class MyService extends Service {

    private final static String TAG = MyService.class.getSimpleName();
    public final static String BUNDLED_LISTENER = "listener";

    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        String logName = intent.getStringExtra("logName");
        ResultReceiver receiver = intent.getParcelableExtra(MyService.BUNDLED_LISTENER);

        Bundle bundle = new Bundle();
        bundle.putString("value", "30");
        receiver.send(Activity.RESULT_OK, bundle);
        return Service.START_NOT_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}
10
user2121