All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ioc.commons.impl.android.flowcontrol.eventbus.AndroidEventBusImpl Maven / Gradle / Ivy

package org.ioc.commons.impl.android.flowcontrol.eventbus;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.ioc.commons.flowcontrol.common.BindRegistration;
import org.ioc.commons.flowcontrol.eventbus.EventBus;
import org.ioc.commons.flowcontrol.eventbus.EventHandler;
import org.ioc.commons.flowcontrol.eventbus.IsEvent;
import org.ioc.commons.utils.FormatterLogger;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

public class AndroidEventBusImpl> implements EventBus {

	private static final FormatterLogger logger = FormatterLogger.getLogger(AndroidEventBusImpl.class);

	private static final String EVENT_INTENT_ACTION = "org.ioc.commons.impl.android.flowcontrol.eventbus.EVENT";
	private static final String EVENT_KEY = "EVENT";
	private static final String EVENT_PARAMETERS_KEY = "EVENT_PARAMETERS";

	private class AndroidEventBusBindRegistration implements BindRegistration {

		private final Context context;
		private final EventStore store;

		public AndroidEventBusBindRegistration(Context context, EventStore store) {
			this.context = context;
			this.store = store;
		}

		@Override
		public void unbind() {
			stored.remove(this.store);

			this.context.unregisterReceiver(this.store.receiver);
		}

	}

	private static class EventReceiver> extends BroadcastReceiver {

		private final EventHandler handler;
		private final Map, BindRegistration> onceHandlers;
		private E event;

		public EventReceiver(E event, EventHandler handler, Map, BindRegistration> onceHandlers) {
			this.event = event;
			this.handler = handler;
			this.onceHandlers = onceHandlers;
		}

		@Override
		public void onReceive(Context context, Intent intent) {
			@SuppressWarnings("unchecked")
			E event = (E) intent.getSerializableExtra(EVENT_KEY);

			if (this.event.equals(event)) {
				if (!onceHandlers.isEmpty()) {
					BindRegistration registration = onceHandlers.remove(handler);
					if (registration != null) {
						registration.unbind();
					}
				}

				Object[] params = (Object[]) intent.getSerializableExtra(EVENT_PARAMETERS_KEY);
				handler.handleEvent(context, event, params);
			}
		}
	}

	private final Map, BindRegistration> onceHandlers = new HashMap, BindRegistration>();

	private final Context context;

	private class EventStore {
		IntentFilter filter;
		EventReceiver receiver;
	}

	private final Set stored = new HashSet<>();
	private boolean active;

	public AndroidEventBusImpl(Context context, boolean initiallyActive) {
		this.context = context;
		this.active = initiallyActive;
	}

	@Override
	public BindRegistration bindEvent(E event, EventHandler handler) {
		IntentFilter filter = new IntentFilter(EVENT_INTENT_ACTION);
		EventReceiver receiver = new EventReceiver(event, handler, onceHandlers);
		EventStore store = addEventReceiver(context, filter, receiver);

		return new AndroidEventBusBindRegistration(context, store);
	}

	private EventStore addEventReceiver(Context context, IntentFilter filter, EventReceiver receiver) {
		EventStore es = new EventStore();

		es.filter = filter;
		es.receiver = receiver;

		stored.add(es);

		if (this.active) {
			context.registerReceiver(receiver, filter);
		}

		return es;
	}

	@Override
	public BindRegistration bindEventOnce(E event, EventHandler handler) {
		BindRegistration registration = bindEvent(event, handler);

		this.onceHandlers.put(handler, registration);

		return registration;
	}

	@Override
	public void fireEvent(E event, Object... params) {
		Intent intent = new Intent(EVENT_INTENT_ACTION);
		intent.putExtra(EVENT_KEY, event);
		intent.putExtra(EVENT_PARAMETERS_KEY, params);

		if (context == null) {
			throw new NullPointerException("Cannot fire event. Empty context returned by " + context);
		}

		context.sendBroadcast(intent);
	}

	@Override
	public Object asEventBus() {
		/*
		 * Android does not have real event bus but broadcast receivers, so
		 * Context could be considered the bus instead.
		 */
		return context;
	}

	public void onCreate() {
		/*
		 * Nothing to do
		 */
	}

	public void onStart() {
		for (EventStore os : this.stored) {
			context.registerReceiver(os.receiver, os.filter);
		}
	}

	public void onResume() {
		this.active = true;
	}

	public void onPause() {
		this.active = false;
	}

	public void onStop() {
		for (EventStore os : this.stored) {
			try {
				context.unregisterReceiver(os.receiver);
			} catch (Exception e) {
				logger.warn(e, "Failure during unregistering reciver. Ignoring it.");
			}
		}
	}

	public void onDestroy() {
		/*
		 * Nothing to do
		 */
	}

	public void onActivityCreated(Bundle savedInstanceState) {
		/*
		 * Nothing to do
		 */
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy