Как определить обратные вызовы в Android?
В течение самого последнего Google IO была презентация о внедрении непринужденных клиентских приложений. К сожалению, это было только обсуждение на высоком уровне без исходного кода реализации.
На этой диаграмме на пути возврата существуют различные разные обратные вызовы другим методам.
![слайд презентации google io]()
Как объявить, что эти методы?
Я понимаю идею обратного вызова - фрагмент кода, который вызывается после того, как произошло определенное событие, но я не знаю, как его реализовать. Единственный способ, с помощью которого я реализовал обратные вызовы до сих пор, переопределял различные методы (например, onActivityResult).
Я чувствую, что у меня есть базовое понимание шаблона проектирования, но я продолжаю спотыкаться о том, как обрабатывать обратный путь.
Ответы
Ответ 1
Во многих случаях у вас есть интерфейс и проходит по объекту, который его реализует. Диалоги, например, имеют OnClickListener.
Как случайный пример:
// 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
}
};
Я, вероятно, испортил синтаксис в варианте 2. Это было раннее.
Ответ 2
Когда что-то происходит в моем представлении, я запускаю событие, которое прослушивает моя деятельность:
//ЗАЯВЛЕННЫЙ (ПОЛЬЗОВАТЕЛЬСКИЙ) ПРОСМОТР
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;
}
//ДЕКЛАРАЦИЯ В ДЕЯТЕЛЬНОСТИ
MyCustomView slider = (MyCustomView) view.findViewById(R.id.slider)
slider.setOnScoreSavedListener(new OnScoreSavedListener() {
@Override
public void onScoreSaved() {
Log.v("","EVENT FIRED");
}
});
Если вы хотите узнать больше о связях (обратных вызовах) между фрагментами, см. здесь:
http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
Ответ 3
Нет необходимости определять новый интерфейс, если вы можете использовать существующий: android.os.Handler.Callback
. Передайте объект типа Callback и вызовите обратный вызов handleMessage(Message msg)
.
Ответ 4
чтобы немного разъяснить ответ дракона (так как мне потребовалось некоторое время, чтобы выяснить, что делать с Handler.Callback
):
Handler
может использоваться для выполнения обратных вызовов в текущем или другом потоке, передавая его Message
s. Message
содержит данные, которые будут использоваться из обратного вызова. a Handler.Callback
может быть передан конструктору Handler
, чтобы избежать непосредственного распространения Handler. таким образом, выполнить некоторый код через обратный вызов из текущего потока:
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: просто понял, что лучший способ получить тот же результат (минус контроль точно, когда нужно выполнить обратный вызов):
post(new Runnable() {
@Override
public void run() {
<code to be executed during callback>
}
});
Ответ 5
Пример реализации метода обратного вызова с использованием интерфейса.
Определите интерфейс, NewInterface.java.
пакет javaapplication1;
public interface NewInterface {
void callback();
}
Создайте новый класс NewClass.java. Он вызовет метод обратного вызова в основном классе.
package javaapplication1;
public class NewClass {
private NewInterface mainClass;
public NewClass(NewInterface mClass){
mainClass = mClass;
}
public void calledFromMain(){
//Do somthing...
//call back main
mainClass.callback();
}
}
Основной класс JavaApplication1.java для реализации интерфейса метода NewInterface - callback(). Он создаст и вызовет объект NewClass. Затем объект NewClass будет обращать его обратный вызов() по очереди.
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");
}
}
Ответ 6
Вы также можете использовать LocalBroadcast
для этой цели. Вот быстрое решение
Создайте широковещательный приемник:
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
}
Вот как вы можете его запустить
Intent intent = new Intent("speedExceeded");
intent.putExtra("currentSpeed", currentSpeed);
intent.putExtra("latitude", latitude);
intent.putExtra("longitude", longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
unRegister приемник в onPause:
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}