I simply want to call methods of a local service from my activity. How can i do that ?
问题:
回答1:
One way to do this is by defining an interface with Android's AIDL and making use of the Binder
subsystem to perform IPC. There is a great set of instructions at the link I posted. I'd start there and then post here if you have questions. Despite being a pretty complex topic (IPC) Android and the Binder
do a really good job of making it pretty dead simple (at least to get started, I'm sure you could make it complicated if you wanted to ;-) )
Edit As pointed out in the comments, this is unnecessary if the Service
and the client are running in the same process. Unless you specify otherwise, this is the default. However, it still works regardless, it just adds a bit more complexity.
回答2:
Here is an example that might help
Server.java:
package com.example.bindservice.binder;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class Server extends Service {
IBinder mBinder = new LocalBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public Server getServerInstance() {
return Server.this;
}
}
public String getTime() {
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mDateFormat.format(new Date());
}
}
Client.java
package com.example.bindservice.binder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.bindservice.binder.Server.LocalBinder;
public class Client extends Activity {
boolean mBounded;
Server mServer;
TextView text;
Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
text.setText(mServer.getTime());
}
});
}
@Override
protected void onStart() {
super.onStart();
Intent mIntent = new Intent(this, Server.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
};
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(Client.this, "Service is disconnected", 1000).show();
mBounded = false;
mServer = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(Client.this, "Service is connected", 1000).show();
mBounded = true;
LocalBinder mLocalBinder = (LocalBinder)service;
mServer = mLocalBinder.getServerInstance();
}
};
@Override
protected void onStop() {
super.onStop();
if(mBounded) {
unbindService(mConnection);
mBounded = false;
}
};
}
回答3:
There is sample code for this right in the Service documentation, under "Local Service Sample":
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
Also for those people suggesting aidl -- if your service and client are all part of your own .apk and running in the same process (the default behavior), there is no need for aidl; it is just additional complexity that doesn't give you anything.
回答4:
I don't know where your problem is, please post some code. Using a Binder, the Activity can have access to the service object. See the examples in the API for creating a connection between activity and service.
Having the service object in your activity, you can simply call:
mService.yourMethod();
We could help you a lot better if you would exactly describe your problem and as I said, post some snippets.