Lors de la dernière publication de Google IO, une présentation portait sur la mise en œuvre d'applications clientes reposantes. Malheureusement, il ne s’agissait que d’une discussion de haut niveau sans code source de l’implémentation.
Dans ce diagramme, sur le chemin de retour, il existe différents rappels à d'autres méthodes.
Comment déclarer ce que sont ces méthodes?
Je comprends l'idée d'un rappel - un morceau de code appelé après un certain événement, mais je ne sais pas comment le mettre en œuvre. Jusqu'à présent, la seule façon dont j'ai implémenté les rappels consistait à surcharger différentes méthodes (onActivityResult par exemple).
Je sens que j'ai une compréhension de base du modèle de conception, mais je continue à me demander comment gérer le chemin de retour.
Dans de nombreux cas, vous avez une interface et transmettez un objet qui l'implémente. Les boîtes de dialogue, par exemple, ont le OnClickListener.
Juste comme exemple aléatoire:
// The callback interface
interface MyCallback {
void callbackCall();
}
// The class that takes the callback
class Worker {
MyCallback callback;
void onEvent() {
callback.callbackCall();
}
}
// Option 1:
class Callback implements MyCallback {
void callbackCall() {
// callback code goes here
}
}
worker.callback = new Callback();
// Option 2:
worker.callback = new MyCallback() {
void callbackCall() {
// callback code goes here
}
};
J'ai probablement foiré la syntaxe dans l'option 2. C'est tôt.
Lorsque quelque chose se passe à mon sens, je déclenche un événement que mon activité écoute:
// DÉCLARÉ EN VUE (PERSONNALISÉE)
private OnScoreSavedListener onScoreSavedListener;
public interface OnScoreSavedListener {
public void onScoreSaved();
}
// ALLOWS YOU TO SET LISTENER && INVOKE THE OVERIDING METHOD
// FROM WITHIN ACTIVITY
public void setOnScoreSavedListener(OnScoreSavedListener listener) {
onScoreSavedListener = listener;
}
// DÉCLARÉ EN ACTIVITÉ
MyCustomView slider = (MyCustomView) view.findViewById(R.id.slider)
slider.setOnScoreSavedListener(new OnScoreSavedListener() {
@Override
public void onScoreSaved() {
Log.v("","EVENT FIRED");
}
});
Si vous voulez en savoir plus sur la communication (rappels) entre fragments, voir ici: http://developer.Android.com/guide/components/fragments.html#CommunicatingWithActivity
Pas besoin de définir une nouvelle interface lorsque vous pouvez utiliser une interface existante: Android.os.Handler.Callback
. Transmettez un objet de type Callback et appelez le handleMessage(Message msg)
du callback.
Exemple d'implémentation d'une méthode de rappel à l'aide d'une interface.
Définissez l'interface, NewInterface.Java.
package javaapplication1;
public interface NewInterface {
void callback();
}
Créez une nouvelle classe, NewClass.Java. Il appellera la méthode de rappel en classe principale.
package javaapplication1;
public class NewClass {
private NewInterface mainClass;
public NewClass(NewInterface mClass){
mainClass = mClass;
}
public void calledFromMain(){
//Do somthing...
//call back main
mainClass.callback();
}
}
La classe principale, JavaApplication1.Java, permettant d'implémenter la méthode d'interface NewInterface - callback (). Il va créer et appeler l'objet NewClass. Ensuite, l'objet NewClass appellera sa méthode callback () à son tour.
package javaapplication1;
public class JavaApplication1 implements NewInterface{
NewClass newClass;
public static void main(String[] args) {
System.out.println("test...");
JavaApplication1 myApplication = new JavaApplication1();
myApplication.doSomething();
}
private void doSomething(){
newClass = new NewClass(this);
newClass.calledFromMain();
}
@Override
public void callback() {
System.out.println("callback");
}
}
pour clarifier un peu la réponse de dragon (puisqu'il m'a fallu un certain temps pour savoir quoi faire avec Handler.Callback
):
Handler
peut être utilisé pour exécuter des rappels dans le fil actuel ou dans un autre thread en le transmettant Message
s. la Message
contient les données à utiliser à partir du rappel. un Handler.Callback
peut être passé au constructeur de Handler
afin d'éviter d'étendre directement Handler. ainsi, pour exécuter du code via callback à partir du thread actuel:
Message message = new Message();
<set data to be passed to callback - eg message.obj, message.arg1 etc - here>
Callback callback = new Callback() {
public boolean handleMessage(Message msg) {
<code to be executed during callback>
}
};
Handler handler = new Handler(callback);
handler.sendMessage(message);
EDIT: je viens de me rendre compte qu’il existe un meilleur moyen d’obtenir le même résultat (sans le contrôle du moment exact pour exécuter le rappel):
post(new Runnable() {
@Override
public void run() {
<code to be executed during callback>
}
});
Vous pouvez également utiliser LocalBroadcast
à cette fin. Voici un bref aperçu
Créer un récepteur de diffusion:
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("speedExceeded"));
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Double currentSpeed = intent.getDoubleExtra("currentSpeed", 20);
Double currentLatitude = intent.getDoubleExtra("latitude", 0);
Double currentLongitude = intent.getDoubleExtra("longitude", 0);
// ... react to local broadcast message
}
Voici comment vous pouvez le déclencher
Intent intent = new Intent("speedExceeded");
intent.putExtra("currentSpeed", currentSpeed);
intent.putExtra("latitude", latitude);
intent.putExtra("longitude", longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
unRegister receiver in onPause:
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}