web-dev-qa-db-fra.com

Utilisation de ResultReceiver dans Android

Fondamentalement, je voudrais établir un rappel vers une activité à partir d'un IntentService. Ma question est très similaire à celle à laquelle nous avons répondu ici:

Service API reposant

Cependant, dans le code de réponse, le code d'activité est considéré comme implémentant un ResultReceiver. Sauf s'il me manque quelque chose, ResultReceiver est en fait une classe, il ne peut donc pas effectuer cette implémentation.

Donc, essentiellement, je demande quelle serait la bonne façon de connecter un ResultReceiver à ce service. Je suis confus avec les concepts Handler et ResultReceiver à cet égard. Tout exemple de code de travail serait apprécié.

59
Bill Eisenhauer
  1. Vous devez créer une classe resultreceiver personnalisée étendue à partir de ResultReceiver

  2. implémente ensuite l'interface resultreceiver dans votre activité

  3. Passez l'objet resultreceiver personnalisé à intentService et dans intentservice, récupérez simplement l'objet récepteur et appelez la fonction receiver.send () pour envoyer quoi que ce soit à l'activité d'appel dans l'objet Bundle.

    voici la classe 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);
            }
        }
    
    }
    

implémente l'interface Myresultreceiver.receiver dans votre activité, créez une variable de classe

Public MyResultReceiver mReceiver;

initialisez cette variable dans onCreate:

mReceiver = new MyResultReceiver(new Handler());

mReceiver.setReceiver(this);

Passez ce mReceiver à l'intentionService via:

intent.putExtra("receiverTag", mReceiver);

et récupérer dans IntentService comme:

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

et envoyer quoi que ce soit à l'activité en utilisant rec comme:

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

cela sera reçu dans onReceiveResult de l'activité. Vous pouvez afficher le code complet sur: IntentService: fournir des données à l'activité

Edit: Vous devez appeler setReceiver (this) dans onResume et setReceiver (null) dans onPause () pour éviter les fuites.

116
SohailAziz

Vous remplacez une méthode en sous-classant. Il n'est pas nécessaire que ce soit une interface pour cela.

Par exemple:

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

J'ai créé un exemple simple qui montre comment utiliser 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