Как определить обратные вызовы в Android? - PullRequest
148 голосов
/ 03 августа 2010

Во время самого последнего Google IO, была презентация о реализации спокойных клиентских приложений.К сожалению, это было только обсуждение высокого уровня без исходного кода реализации.

На этой диаграмме на пути возврата существуют различные различные обратные вызовы для других методов.

google io presentation slide

Как мне объявить, что это за методы?

Я понимаю идею обратного вызова -фрагмент кода, который вызывается после определенного события, но я не знаю, как его реализовать.Единственный способ, которым я реализовал обратные вызовы, это переопределение различных методов (например, onActivityResult).

Мне кажется, что у меня есть базовое понимание шаблона проектирования, но я продолжаю понимать, какобрабатывать обратный путь.

Ответы [ 6 ]

211 голосов
/ 03 августа 2010

Во многих случаях у вас есть интерфейс и вы передаете объект, который его реализует.Например, диалоги имеют 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. Это рано.

50 голосов
/ 21 июля 2012

Когда что-то происходит на мой взгляд, я запускаю событие, которое слушает моя деятельность:

// ОБЪЯВЛЕНО (ПОЛЬЗОВАТЕЛЬСКИЙ) ВИД

    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

37 голосов
/ 22 апреля 2012

Нет необходимости определять новый интерфейс, когда вы можете использовать существующий: android.os.Handler.Callback. Передайте объект типа Callback и вызовите функцию handleMessage(Message msg).

для функции обратного вызова.
24 голосов
/ 17 июля 2015

Пример реализации метода обратного вызова с использованием интерфейса.

Определить интерфейс, 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 будет вызывать свой метод callback () по очереди.

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");
    }

}
20 голосов
/ 19 октября 2012

, чтобы уточнить ответ дракона (так как мне потребовалось некоторое время, чтобы понять, что делать с Handler.Callback):

Handler может использоваться для выполнения обратных вызовов в текущем или другом потоке, передав его Message с. Message содержит данные для обратного вызова. 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);

РЕДАКТИРОВАТЬ: только что понял, что есть лучший способ получить тот же результат (минус контроль точно, когда выполнить обратный вызов):

post(new Runnable() {
    @Override
    public void run() {
        <code to be executed during callback>
    }
});
11 голосов
/ 29 августа 2015

Вы также можете использовать 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);

отменить регистрацию приемника в onPause:

protected void onPause() {
  super.onPause();
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...