一、通过startService方式启动的服务:(后台处理工作),只能通过intent传递参数,但不能与Activity交互。
服务不能自己启动,需要通过其他的应用程序调用才能启动。
启动服务的应用,需要的处理:
1、注册服务:<service android:name=".LocalService"></service> //LocalService:服务的类名
2、启动服务:startService(new Intent(MainActivity.this,LocalService.class)); //此处可以通过intent给服务传递参数。使用这种方式启动的Service,当启动它的Activity被销毁时,是不会影响到它的运行的,这时它仍然继续在后台运行它的工作。直至调用StopService(Intent service)方法时或者是当系统资源非常紧缺时,这个服务才会调用onDestory()方法停止运行
3、停止服务:stopService(new Intent(MainActivity.this,LocalService.class));
服务的处理:
1、onCreate():当服务创建时,调用该方法。
2、onStartCommand(Intent intent, int flags, int startId):当通过startService方法启动服务时调用,在此可以通过Intent获取应用传过来的参数
3、onDestroy():当服务通过stopService被停止时调用。
二、通过bindService来启动的Service(在本地同进程内与Activity交互)
绑定服务应用端的处理:
1、注册服务:<service android:name=".LocalService"></service> //LocalService:服务的类名
2、创建服务连接监听器:
//是设置服务连接监听器,目的是:当服务绑定和停止时做一些处理
private ServiceConnection mConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder service)
{//当服务连接时调用,并可获取服务的binder接口,调用服务在binder接口内定义的函数
iService=(IService)service;
service.getName(); }
public void onServiceDisconnected(ComponentName className)
{//服务停止时做一些处理}
};
3、绑定方式启动服务:bindService (Intent service,ServiceConnection conn, int flags) //传递服务连接器对象。
4、停止服务:unbindService(ServiceConnection mConnection)//指定要停止哪个连接器启动的服务。
服务端的处理:
1、onCreate():当服务创建时,调用该方法。
2、服务内定义binder接口:接口内有服务要提供给连接该服务客户端调用的方法
public class MyBind extends Binder implements IService{
public String getName() { return "name"; }}
3、构造服务端接口:private MyBind myBind=new MyBind();
4、绑定事件调用:当bindService时调用,并放回给客户端服务端接口
public IBinder onBind(Intent arg0)
{ return myBind; }
5、onUnbind(Intent intent):当客户端unbindService时调用。
整个程序的运行过程是这样的:点用户点击绑定服务按钮时Activity调用bindService()方法,然后系统就去调用onCreate创建服务,然后系统继续调用onBind()方法向Activity传递一个IBinder类型的对象, 是传递给Activity里的ServiceConnection里的onServiceConnected(ComponentName name, IBinder service)的第二个参数,然后通过这个参数可以获得IService的方法。进行本地的Activity和Service交互。
特别说明:以上两种方法都是在同一个进程里进行的,而且服务要同客户端应用一起打包。要实现跨进程的通信需要用下面的方式
三、AIDL方式的Service(进行跨进程的通信)
AIDL(Android Interface Definition Language) IPC机制是面向对象的,轻量级的。通过AIDL定义的接口可以实现服务器端与客户端的IPC通信。
AIDL和服务端的编写:
1、在Eclipse 创建Android工程,选择不创建activity
2、在工程的src文件夹内,创建包的文件夹,在文件夹内建立一个扩展名为aidl的文件:
package com.thtf.svraidl;
interface IMyService {
String getValue();
}
3、eclipse 里的ADT会自动生成一个IMyService.java文件。
4、编写一个MyService类。MyService是Service的子类,在MyService类中定义了一个内嵌类(MyServiceImpl),该类是IMyService.Stub的子类。MyService类的代码如下:
public class MyService extends Service
{
public class MyServiceImpl extends IMyService.Stub
{
public String getValue() throws RemoteException
{
return "aidl服务方法";
}
}
public IBinder onBind(Intent intent)
{
return new MyServiceImpl();
}
}
说明:在编写上面代码时要注意如下两点:IMyService.Stub是根据IMyService.aidl文件自动生成的,一般并不需要管这个类的内容,只需要编写一个继承于IMyService.Stub类的子类(MyServiceImpl类)即可。 onBind方法必须返回MyServiceImpl类的对象实例,否则客户端无法获得服务对象。
5、在AndroidManifest.xml文件中配置MyService类,代码如下:
<service android:name=".MyService" >
<intent-filter>
<action android:name="com.thtf.svraidl.IMyService" />
</intent-filter>
</service>
注意:action里的包名和接口名不要写错。
客户端的编写:
1、新建一个Eclipse Android工程(svraidlclient),并将自动生成的IMyService.java文件连同包目录一起复制到工程的src目录中
2、把AISL接口导入进来:import com.thtf.svraidl.IMyService。
3、创建服务连接,并在服务连接的时候,获取服务对象:
private IMyService myService = null;
private ServiceConnection serviceConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName name, IBinder service)
{
// 获得服务对象
myService = IMyService.Stub.asInterface(service);
}
}
4、绑定的方式启动服务:
// 绑定AIDL服务
bindService(new Intent("com.thtf.svraidl.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE);
5、调用服务的方法:myService.getValue()
四、APK包之间调用(类似服务的进行跨进程通信,可以传递参数,获取结果,但不能调用方法)
例如,A apk传递参数给B apk并获取B返回的数据,实现如下:
A apk的处理:
Intent intent = new Intent(); //创建一个通信意图
intent.setClassName("com.thtf", "com.thtf.PermitActivity"); //设置要同哪个类通信
intent.putExtra("filename", "泰囧"); //通信意图内放置要传递的参数
startActivityForResult(intent, 0); //启动要通信的activity
//等待返回结果处理事件
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)//判断返回码是否正确
{
Bundle extras = data.getExtras();//通过意图获取返回的数据
String result = "结果:" +extras.getString("retvalue");//提取数据
}
}
B apk的处理:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bundle extras = getIntent().getExtras();//获得意图传递的参数
if(extras != null)
{
String filename = extras.getString("filename");//获取参数值
String retvalue = invokeWs(filename);//根据参数值进行事务处理,并返回处理的结果
//组成标准intent参数
Bundle bundle = new Bundle();
bundle.putString("retvalue", retvalue);
//新建intent,并把参数放入其中
Intent intent = new Intent();
intent.putExtras(bundle);
// 设置要返回的intent,给调用者
setResult(RESULT_OK, intent);
}
finish();
}