I have tried to start a service and bind to the service in my Activity's onCreate() method. When I try to call a function from service like commSessionManagerService.startCommandUpperM() afterwards, a NullPointerException occurs. Here is the code that I use to start the service and bind to it:
Intent startIntent = new Intent(this, CommSessionManagerService.class);
startService(startIntent);
Intent bindIntent = new Intent(this, CommSessionManagerService.class);
bindService(bindIntent, conn, Context.BIND_AUTO_CREATE);
If I move the function startCommandUpperM() to onStartCommand() in the CommSessionManagerService, the onCreate method will take several seconds to complete. As a related note, I have a created and started a thread in the startCommandUpperM() function.
This is because your Service is actually bound on the UiThread. As onCreate also runs on UiThread, your call to bindService result in Handler.post(Runnable) be called on the main thread's handler.
So when bindService returns, the Service isn't already bound.
To circumvent this problem, you should put your code using your Service inside ServiceConnection.onServiceConnected().
Related
I built a class called MService extend Service in Android Studio , I started the service like this: - inside onClick associated with a button-
Intent serviceIntent = new Intent(getApplicationContext(), MService.class);
serviceIntent.putExtra("ID", "1");
startService(serviceIntent);
The Service onStartCommand method lunched and worked pretty good..
The problem is I don't know how to end the Service when a Button clicked, I tried to do this:
stopService(new Intent(getApplicationContext(), MService.class));
inside a onClick method , the onDestroy lunched, but the Service still running
How can I stop it?
inside a onClick method , the onDestroy lunched, but the Service still running
If onDestroy() of your service was called, then afterwards, the service is not running. Your code might still be running.
If you start things in a service, such as a background thread, it is your job to stop them and clean that up, typically in your onDestroy() method.
Found an interesting observation with foreground service, if we stop the service immediately right just after start foreground service we get this error as Context.startForegroundService() did not then call Service.startForeground(). Doesn't matter whether we start notification from onCreate or onStartCommand of service.
Intent intent = new Intent(this, MyService.class)
startForegroundService(intent);
stopService(intent);
But if I add a delay then it's working as expected, any thought on this ?
Intent intent = new Intent(this, MyService.class)
startForegroundService(intent);
new Handler(Looper.getMainLooper()).postDelayed(() -> stopService(intent), 0);
In order to get rid of this error this is how I fixed
I didn't found any proper documentation on developer website but this is what
I did in order to solve Context.startForegroundService() did not
then call Service.startForeground() issue.
If we want to stop foreground service do not call outside the service
class using stopService(intent) instead create an intent action,
start the foreground service then stop the service using stopSelf from
service onStartCommand.
Intent serviceIntent = new Intent(context, MyService.class);
serviceIntent.setAction(ACTION_STOP_SERVICE);
ContextCompat.startForegroundService(context, serviceIntent);
Starting a service is not synchronous and the service is not up and running when the start call returns. Think of it as posting a message to your main thread looper queue that get processed later.
Now your Handler approach is also doing the same kind of thing to postpone the execution - post a runnable to the main thread looper queue. It gets processed after the previous messages in the queue have been processed, so there's some Service startup lifecycle code that has been executed before the stopService() is invoked.
I'm using service to run Bluetooth in background,but i don't no how to send data from another activity to service
Service and other activities work in the same process
To start a Service, use following statement:
Intent intent = new Intent(context, Service.class);
// intent put some extra
startService(intent);
Calling this statement firstly, Service call onCreate() method and onStartCommand().
Not firstly, Service just call onStartCommand().
You can check if it is called firstly by extra in intent.
So you can send data with the same method startService(Intent intent).
Service works in another process
use [bindService](https://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)) and AIDL
It is suggested that make service and other activities work in the same process when your target is not complex.
When is onStartCommand of a service exactly executed?
In the following code my service is started from the onCreate in my activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, CenseDroidService.class);
//onStartCommand is not extecuted immediatly after startService
startService(intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
So when does the Android system decide to call onStartCommand? All that I know is that is runs on the main thread some time after calling startService. The onCreate is fully executed before onStartCommand is called.
From the documentation.
Called by the system every time a client explicitly starts the service by calling startService(Intent), providing the arguments it supplied and a unique integer token representing the start request
What this means is, every time you call startService(intent) with an Intent, then onStartCommand will be called. If you have a hundred Activities that all need to start and bind to this service, then they will all call startService() and onStartCommand will be called.
Now when it is exactly called is a bit trickier to answer. It is sometime in the future which is why your ServiceConnection works asynchronously. Most likely it can be within the next UI Thread cycle, but it is not something you should rely on.
If you need a reasonable knowledge of when the Service started, you could use the LocalBroadcastManager to broadcast the event to all registered listeners. The LocalBroadcastManager#sendBroadcastSync will actually block until all listeners respond so it may be useful for this scenario.
I have used the method finish() before in several activities without problems.
however when I tried to call it inside of the broadcast receiver I get the error message from the compiler that "the method finish() is undefined for the type AudioService"
AudioService is the name of my Service class in my Android app.
If there is no finish() method in a Service than what can I call to kill this Service dead?
use this line:
this.stopSelf();
to kill itself.
Or from outside use stopService(intent);
you can try as to stop your AudioService service from broadcast receiver :
Intent intent = new Intent();
intent.setClass(context, AudioService.class);
context.stopService(intent);
where context is first param which you received in on Receive of broadcast receiver