I'm trying to get my Services object and I'm doing that with this code
public class Service extends android.app.Service {
private Handler handler = new Handler();
static Service SELF;
MainActivity mainActivity;
BluetoothSPP bluetoothSPP;
public static Service getInstance() {
return SELF;
}
#Override
public void onCreate() {
super.onCreate();
SELF = this;
}
}
but after starting service getInstance() gives null. why?
Service and Activity is a different components, managed by Android, so you should not save reference to Activity insie Service.
Solution in this case - use Service binding - you can move all your methods into separate interface, by which your Service and Activity will communicate and return it from Binder once Service is bound to Activity. See: https://developer.android.com/guide/components/bound-services.html, Bind service to activity in Android
Related
I have an app that the MainActivity has a method (called doUpdate()) that is called from a button hit. This uses the MainActivity's public variables to access a database, perform some updates, and update some records. This works well.
We now need to automate this with a PeriodicTask as well.
I created a GCMTaskManager service as follows:
public class MyPeriodicTaskService extends GcmTaskService {
public MyPeriodicTaskService() {
}
#Override
public int onRunTask(TaskParams taskParams) {
Log.i("MYLOG","Task Running...");
return 0;
}
}
In my MainActivity, onCreate(), I setup the PeriodicTask as follows:
GcmNetworkManager networkManager=GcmNetworkManager.getInstance(this);
PeriodicTask task=new PeriodicTask.Builder()
.setService(MyPeriodicTaskService.class)
.setPeriod(60)
.setFlex(30)
.setRequiresCharging(true)
.setTag("UpdateSchedule")
.build();
networkManager.schedule(task);
By watching the LOG, I know that the onRunTask() fires periodically as I hoped.
Now I need to call my MainActivity method... doUpdate(). Because this method is declared PUBLIC VOID and not STATIC, I can't call it from the services doRunTask(). If I attempt to make it a STATIC PUBLIC VOID then the MainActivity variables can't be accessed properly as needed for the internal processing steps.
How do I get around this... any recommendations?
There is android application which stored data into the sqlite. I keep a list of routes in databases table.I display the data on the active route on the screen/To release the processor, I use static List inside service.To release the processor, I use static List inside service. I change the list when receiving data from the server.
public class NetworkService extends Service{
private static NetworkService instance = null;
private static List<RouteTask> routeTaskList;
private static LoadRoutesTask loadRoutesTask;
private static RouteChangedListener rtListener ;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
if (instance == null) {
instance = this;
NetworkManager.updateNetworkInfo(this);
NetworkManager.setNetworkListener(this);
}
}
public static Context getCurrentContext() {
return instance;
}
public static boolean hasInstance() {
return instance != null;
}
public static void setRouteTaskList(List<RouteTask> rtList)
{
routeTaskList = rtList ;
}
public static List<RouteTask> getRouteTask(){
return routeTaskList;
}
}
In application i can set value
NetworkService.setRouteTaskList(list);
or get value :
List<RouteTask> = NetworkService.getRouteTaskList();
My application usually use routeTaskList instead of sql query for data table.
The task now is change the service, for the android development standards. I removed static field and Now, I run a service through intents (startService(intent)). How Can I remove static settter and getter for routeTaskList object ?
You can provide the Service with the list of tasks as extras in the Intent you use in the startService() call. This replaces your static setter.
To get the list of tasks is more complicated. Options:
You could use AIDL and bind to the Service and then call a method to get the list of tasks
You could call startService() with an Intent that asks the Service to broadcast the list of tasks. In the Service.onStartCommand() you could then send a broadcast Intent which contains the list of tasks as extras.
You could have the Service send a sticky broadcast Intent which contains the list of tasks every time the list changes. Your app would then use registerReceiver() call to read the most recently sent sticky broadcast.
I would like to inject a bound service into my activity via Dagger2.
My Service is declared as follow:
Public class MyService extends Service{
private final IBinder mBinder = new LocalBinder();
...
public class LocalBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void doBackgroundTask() {
...
}
}
My Activity:
public abstract class MainActivity extends AppCompatActivity {
#Inject
MyService service;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
service.doBackgroundTask();
...
}
How would you achieve that ? Where will you put the ServiceConnection (into a base class, inside the module) ?
Thanks a lot.
I don't think that injecting the service that way (via injected field) will work because you don't control the instantiation of the service's object.
If your service contains fields that need to be injected you will have to inject in onCreate() the same way you inject your activities, i.e. calling DaggerMyAppComponent.inject(this).
About the ServiceConnection: you will have to do it the usual way as described in http://developer.android.com/guide/components/bound-services.html
I was dealing with the same concept/problem and like #Ognyan says - you won't have control over creating service.
I think this: How to access service functions from fragment, which is bound to parent activity in Android? might help you.
You may instantiate service in Application/Activity and communicate with it as described in the attached link.
You may also think of putting the interface (which is communicating with service) in base abstract class (BaseActivity or BaseFragment) which Fragment/Activity inherits and then easily reach the interface in any fragment or activity you need.
Hope it solves your issue.
I'm working in an app for android. I have a Service to manage the background process of streamming. Then I have an object AudioPlayer that manages the MediaPlayer instance and it get called from the service. But the problem I have is with the listener onPrepared, because it's within my AudioPlayer but I need that when it gets trigger send a message from my object AudioPlayer to my Service. Is it that possible?
I can try to put the logic of my MediaPlayer within Service, but I want to keep things decouple.
Yes It is possible.For communication between service and fragment you can use
1.BroadCast Receiver or 2.Messenger
Using messengers refer this link Communication between an Application class and Service in Android
Create a public interface that allows you to communicate between your service and object.
public interface MyListener {
public void receiveNotification();
}
After that, you have to make your object implements that interface.
public class MediaObject implements MyListener {
public void init () {
InitService.getService.addListener(this);
}
#Override
public void receiveNotification () {
//what you want to do
}
//rest of your class
To make it work you should have in your service class sth like:
public class YourService extends Service {
MyListener listener;
public YourService static getService () {
return YourService.this;
}
public void addListener (MyListener listener) {
this.listener = listener;
}
public void methodYouWantToCommunicateWithObject () {
//your code
if (listener!= null) {
listener.receiveNotification();
}
}
I making Service with Handler and I need Handler to use some Service methods. As Handler must be static, I can access Service methods without Service reference in Handler.
So I did this way:
private static class ServiceHandler extends Handler {
MyService service;
public ServiceHandler(MyService service) {
this.service = service;
}
#Override
public void handleMessage(Message msg) {
...
}
}
But also found that this is the right way to do the job:
private static class ServiceHandler extends Handler {
private final WeakReference<MyService> mMyService;
public ServiceHandler(MyService service) {
mMyService = new WeakReference<MyService>(service);
}
#Override
public void handleMessage(Message msg) {
MyService service = mMyService.get();
...
}
}
What is the difference in this two ways to use Service in Handler?
The first code example sets a member variable to a reference of the calling Service (which I assume is the outer class of this inner class). This is exactly the same as if you had removed the static keyword for the inner class, because now the inner class is holding a reference to an instance of the Service class (which is what you are usually trying to avoid when you use the static keyword).
The second code example uses a weak reference, which means that the garbage collector can clean up (destroy) the instance of the Service class, even though you are holding a reference to it in your Handler. If that occurs, the call to mMyService.get() will return null, so you had better check for that in your code.
In practice, there are no differences between these 2 code examples since you won't be using the Handler once the Service has been destroyed.