Service is a Context by itself. So if you need the Context
only, you can just call this
in your Service
class.
Alternatively, you should pass the Activity
to the service before starting it. Make sure you pass the Activity
after calling super.onCreate(bundle);
However, you should not manipulate your Activity
or it's views from a Service
. A better way is notifying your Activity
from your Service
.
Notify activity from service
Edit: Observer pattern
Create a new class called NotificationCenter.java
public class NotificationCenter {
private static int totalEvents = 1;
public static final int updateActivity = totalEvents++;
// you can add more events
// public static final int anotherEvent = totalEvents++;
private final SparseArray<ArrayList<Object>> observers = new SparseArray<>();
private final SparseArray<ArrayList<Object>> removeAfterBroadcast = new SparseArray<>();
private final SparseArray<ArrayList<Object>> addAfterBroadcast = new SparseArray<>();
private int broadcasting = 0;
public interface NotificationCenterDelegate {
void didReceivedNotification(int id, Object... args);
}
private static volatile NotificationCenter Instance = null;
public static NotificationCenter getInstance() {
NotificationCenter localInstance = Instance;
if (localInstance == null) {
synchronized (NotificationCenter.class) {
localInstance = Instance;
if (localInstance == null) {
Instance = localInstance = new NotificationCenter();
}
}
}
return localInstance;
}
public void postNotificationName(int id, Object... args) {
broadcasting++;
ArrayList<Object> objects = observers.get(id);
if (objects != null && !objects.isEmpty()) {
for (int a = 0; a < objects.size(); a++) {
Object obj = objects.get(a);
((NotificationCenterDelegate) obj).didReceivedNotification(id, args);
}
}
broadcasting--;
if (broadcasting == 0) {
if (removeAfterBroadcast.size() != 0) {
for (int a = 0; a < removeAfterBroadcast.size(); a++) {
int key = removeAfterBroadcast.keyAt(a);
ArrayList<Object> arrayList = removeAfterBroadcast.get(key);
for (int b = 0; b < arrayList.size(); b++) {
removeObserver(arrayList.get(b), key);
}
}
removeAfterBroadcast.clear();
}
if (addAfterBroadcast.size() != 0) {
for (int a = 0; a < addAfterBroadcast.size(); a++) {
int key = addAfterBroadcast.keyAt(a);
ArrayList<Object> arrayList = addAfterBroadcast.get(key);
for (int b = 0; b < arrayList.size(); b++) {
addObserver(arrayList.get(b), key);
}
}
addAfterBroadcast.clear();
}
}
}
public void addObserver(Object observer, int id) {
if (broadcasting != 0) {
ArrayList<Object> arrayList = addAfterBroadcast.get(id);
if (arrayList == null) {
arrayList = new ArrayList<>();
addAfterBroadcast.put(id, arrayList);
}
arrayList.add(observer);
return;
}
ArrayList<Object> objects = observers.get(id);
if (objects == null) {
observers.put(id, (objects = new ArrayList<>()));
}
if (objects.contains(observer)) {
return;
}
objects.add(observer);
}
public void removeObserver(Object observer, int id) {
if (broadcasting != 0) {
ArrayList<Object> arrayList = removeAfterBroadcast.get(id);
if (arrayList == null) {
arrayList = new ArrayList<>();
removeAfterBroadcast.put(id, arrayList);
}
arrayList.add(observer);
return;
}
ArrayList<Object> objects = observers.get(id);
if (objects != null) {
objects.remove(observer);
}
}
}
Then make your Activities
look like this, you receive messages from the Service
in didReceivedNotification()
public class YourActivity implements NotificationCenter.NotificationCenterDelegate {
@Override
public void onPause() {
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.updateActivity);
super.onPause();
}
@Override
public void onResume() {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateActivity);
super.onResume();
}
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.updateActivity) {
// do something with your activity, your service called this
}
}
}
Finally send messages in your Service
to all the Activities
which are listening:
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateActivity, optionalData);
Which is very nice, you don't have to pass Activity instances.
NotificationCenter source is from Telegram.