It is my understanding that if I want a service to run even if nothing is bounded to it, then it must first be started with startService(Intent i).
My question is WHAT IF I want to bind to the service immediately after I start it, would the following code guarantee the service is created with startService()?
Static method within the service class:
public static void actStart(Context ctx) {
Intent i = new Intent(ctx, BGService.class);
i.setAction(ACTION_START);
ctx.startService(i);
}
The binding activity:
BGService.actionStart(getApplicationContext());
bindService(new Intent(this, BGService.class), serviceConnection, Context.BIND_AUTO_CREATE);
I am not sure what you are trying to do here, but "Context.BIND_AUTO_CREATE" creates the service then binds to the service even if it hasn't been started.
Now if you want to access it immediately after binding, you can use the onServiceConnected() method of the serviceConnection:
new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
//put your code here...
} ...
To add to Bugdayci's answer, a complete example is as follows:
ServiceConnection myConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
... your code that needs to execute on service connection
}
#Override
public void onServiceDisconnected(ComponentName name) {
... your code that needs to execute on service disconnection
}
};
Intent intent = new Intent(this, TheServiceClassName.class);
bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
...
Without the bindService at the end, the onServiceConnected() code will not execute.
Related
Normal way of using a bound service:
private ServiceConnection musicConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
MusicBinder binder = (MusicBinder)service;
//get service
musicSrv = binder.getService();
//pass list
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
Intent playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
Instead of this, can't we use this:
MusicService music=new MusicService();
If yes, will there be any differences between the two instances obtained in two different ways?
Bind service or start service will result in a corresponding call to the target service's life cycle methods.
If this service is not already running, it will be instantiated and started (creating a process for it if needed); if it is running then it remains running.
New a service is just create a new object, means nothing, system knows nothing about it.
Just like activity, you cannot new a activity, you should start a activity, then ActivityManager will be response for create the Activity instance and calls its onCreate method.
I'm developing a service started from activity. The service starts a thread that after a long work should call a method from the activity. How can I deliver link at the activity to the thread?
You could just simply bind to the service in order to start it. When bounded, you get the binder in your activity and register a callback in your service. When your thread has finished you call the callback method which goes up to your activity.
In other word, use bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) and get the binder from the serviceConnection implementation
private static ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinder = (YourBinder) service;
mBinder.registerCallback(yourCallbackImplementation);
}
};
And you use yourCallbackImplementation to get messages from the service.
Let me start by saying I've been searching for a long time, found a lot of similar questions (on SO) but I can't find anything to solve this yet:
I have a Service (jobcrawler) that is started by calling startservice().
Within this service, I am starting a long-running thread, which at some point is calling a class (webservice) whose init looks like this:
public webservice(Context context) {
this.context = context;
this.db = new DatabaseHandler(this.context);
this.access_token = db.getAuthKey();
}
After some network calls, the class(webservice) receives data in a method called recieveData().
Inside recieveData I am attempting to bind to the service as follows:
if (!isBound) {
// not bound yet, then bind to the service.
Intent intent = new Intent(this, jobcrawler.class);
bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
Now, I'm getting nullpointerexemption on the line where I call bindservice. Note, that I'm not actually attempting to do anything with the service yet. I'm just trying to bind to it.
any help would be appreciated... if I had hair I'd be pulling it out! lol
Here's some additional code that I think is relevant.
myConnection:
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,IBinder service) {
Log.e("webservice", "service is connected");
MyLocalBinder binder = (MyLocalBinder) service;
myService = binder.getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
Log.e("webservice", "service is disconnected");
isBound = false;
}
};
binder from service called MyLocalBinder:
public class MyLocalBinder extends Binder {
public jobcrawler getService() {
Log.e("Job Crawler", "returning self");
return jobcrawler.this;
}
}
service's onbind method:
private final IBinder myBinder = new MyLocalBinder();
#Override
public IBinder onBind(Intent arg0) {
Log.d("JobCrawler Service", "Service is bound");
return myBinder;
}
oh and this is where I load the class from the thread inside the service, just in case I should be using a different context or something:
private webservice ws= new webservice(getBaseContext());
I know it's a bit late, but I ran upon the same problem and maybe some googlers will be happy :)
So for me the following worked:
Call the bindService method in reference to your context:
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
My activity starts a Service, and when I close my app, the service continues to run.
OK, that's right. But when I open my application again, in the activity, I need to know the value of a public variable defined on the running Service(class) that I've started previously.
How can I do that?
Thanks
If you are binding your Activity to the Service, you should have an implementation of the Binder interface in your Service, e.g.
public class ServiceBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
In your Activity, create a new ServiceConnection class which will be used to give you access to your Service:
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mMyService = ((MyService.ServiceBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mMyService = null;
}
};
Here the member variable mMyService will give you access to all public members of your Service class.
To create the connection, implement doBindService and doUnbindService in your Activity:
void doBindService() {
bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
}
void doUnbindService() {
// Detach our existing connection.
unbindService(mConnection);
}
Hope this helps!
If you don't call unbindService, your activity still have connection to service and you can simply check the variable through the service's method.
You could use messenger.
As per android website
A messenger is reference to a Handler, which others can use to send messages to it. This allows for the implementation of message-based communication across processes, by creating a Messenger pointing to a Handler in one process, and handing that Messenger to another process.
I need a service that run at different process and start at boot .
Also My Application should communicate with that ,
Also I do not want allow other appliaction to use my service .
is there any way ?
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
service = ((BoxService.MyBinder) binder).getService();
Toast.makeText(mainActivity.this, "Connected", Toast.LENGTH_SHORT)
.show();
}
public void onServiceDisconnected(ComponentName className) {
service = null;
}
};
void doBindService() {
bindService(new Intent(this, BoxService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
This works well when I use service at my process , but when I want to use that at diffrent process , I get error in binding ,
What can I do ?
http://marakana.com/forums/android/examples/60.html
See this link
AddFenceActivity.this.startService(new Intent(
AddFenceActivity.this, Location_Services.class));