Activity访问service有两种方式,第一种是通过Ibinder接口实现步骤如下
在Service类中
public class PlayerService extends Service {
private final IBinder binder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public class MyBinder extends Binder {
public PlayerService getService() {
return PlayerService.this;
}
}
}
通过MyBinder内部类得到当前service的实例
在要访问service的activity中
/**
* 在PlayerService类中定义了一个MyBinder类,该类实际上是为了获得PlayerService的对象实例的。
* 在ServiceConnection接口的onServiceConnected方法中的第2个参数是一个IBinder类型的变量,
* 将该参数转换成PlayerService.MyBinder对象,并使用MyBinder类中的getService方法获得PlayerService对象。
* 在获得PlayerService对象后,就可以在Activity中随意操作PlayerService了。
*/
public class PlayerActivity extends Activity{
private PlayerService serviceBinder;
ServiceConnection connection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
serviceBinder = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
serviceBinder = ((PlayerService.MyBinder)service).getService();
}
};
}
然后调用bindService() 建立连接。
这里的代码是跳转并绑定service
Intent i=new Intent();
i.setClass(PlayerActivity.this, PlayerService.class);
i.putExtra("mp3info", mp3Info);
i.putExtra("MSG", AppConstant.PalyerMsg.PRE_MSG);
startService(i);
bindService(i, connection, Context.BIND_AUTO_CREATE);
得到serviceBinder后,就可以通过serviceBinder调用service里面的方法了。
第二种方式是通过aidl,具体实现如下
1.建立aidl文件,如果aidl文件的内容是正确的话,ADT会自动生成一个java接口文件(*.java)
2.建立服务类(Service的子类)
3.实现由aidl文件生成的java接口
4.在AndroidManifest.xml文件中配置aidl服务。要注意的是<action>标签中android:name的属性值就是要引用该服务的ID,也就是Intent类的参数值.
1.Aidl文件内容
package net.blogjava.mobile.aidl;
interface IMyService
{
String getValue();
}
2.编写完后会生成一个同名的java文件,这里是IMyService.java我们不需要管这个java文件
3.编写一个MyService类. MyService是Service的子类,在MyService类中定义了一个内嵌类(MyServiceImpl)该类是IMyService.Stub的子类.
package net.blogjava.mobile.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class MyService extends Service {
public class MyServiceImpl extends IMyService.Stub {
@Override
public String getValue() throws RemoteException {
// TODO Auto-generated method stub
return "Android/OPhone开发讲义";
}
}
@Override
public IBinder onBind(Intent intent) {
return new MyServiceImpl();
}
}
4.在AndroidManifest.xml文件中配置MyService类,因为这里是跨进程访问service所以是用指定action的方式.如果在同一个进程中可以不用过滤的intent-filter,只写一个
<service android:name=".MyService" >这样的就可以了,此处是跨进程所以代码写成这样:
<service android:name=".MyService" >
<intent-filter>
<action android:name="net.blogjava.mobile.aidl.IMyService" />
</intent-filter>
</service>
下面是客户端的代码
1. 将自动生成的IMyService.java文件连同包一起复制到客户端工程项目中
2. 客户端的代码如下(可以参考android 项目示例src目录下ch08_aidlclient和ch08_aidl)
package net.blogjava.mobile;
import net.blogjava.mobile.aidl.IMyService;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
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;
public class Main extends Activity implements OnClickListener {
private IMyService myService = null;
private Button btnInvokeAIDLService;
private Button btnBindAIDLService;
private TextView textView;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService = IMyService.Stub.asInterface(service);
btnInvokeAIDLService.setEnabled(true);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnBindAIDLService:
bindService(new Intent("net.blogjava.mobile.aidl.IMyService"),
serviceConnection, Context.BIND_AUTO_CREATE);
break;
case R.id.btnInvokeAIDLService:
try {
textView.setText(myService.getValue());
} catch (Exception e) {
}
break;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService);
btnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService);
btnInvokeAIDLService.setEnabled(false);
textView = (TextView) findViewById(R.id.textview);
btnInvokeAIDLService.setOnClickListener(this);
btnBindAIDLService.setOnClickListener(this);
}
}