Android Service

很多情况下,一些与用户很少需要产生交互的应用程序,我们一般让它们在后台运行就行了,而且在它们运行期间我们仍然能运行其他的应用。

为了处理这种后台进程,Android引入了Service的概念。Service在Android中是一种长生命周期的组件,它不实现任何用户界面。最 常见的例子如:媒体播放器程序,它可以在转到后台运行的时候仍然能保持播放歌曲;或者如文件下载程序,它可以在后台执行文件的下载。

让我们来看下如何创建Service:
创建一个Service
Android中已经定义了一个 ‘Service’类,所有其他的Service都继承于该类。Service类中定义了一系列的生命周期相关的方法,如: onCreate(), onStart(), onDestroy()。参见下例:

package com.wissen.testApp.service;

public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, “Service created…”, Toast.LENGTH_LONG).show();
}

@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, “Service destroyed…”, Toast.LENGTH_LONG).show();
}
}

上例中的这个Service主要做了这些事:当服务创建和销毁时通过界面消息提示用户。
如Android中的其它部件一样, Service也会和一系列Intent关联。Service的运行入口需要在AndroidManifest.xml中进行配置,如下:

<service class=”.service.MyService”>
<intent-filter>
<action android:value=”com.wissen.testApp.service.MY_SERVICE” />
</intent-filter>
</service>

之后我们的Service就可以被其他代码所使用了。

使用Service:
应用程序可以通过调用 Context.startService方法来启动Service。如果当前没有指定的Service实例被创建,则该方法会调用 Service的onCreate方法来创建一个实例;否则调用Service的onStart方法。参见下列代码:

..
Intent serviceIntent = new Intent();
serviceIntent.setAction(”com.wissen.testApp.service.MY_SERVICE”);
startService(serviceIntent);
..

以上代码调用了startService方法,Service会持续运行,直到调用stopService()或stopSelf()方法。
还有另一种绑定Service的方式:


ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(”INFO”, “Service bound “);
}

@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.i(”INFO”, “Service Unbound “);
}
};

bindService(new Intent(”com.wissen.testApp.service.MY_SERVICE”), conn, Context.BIND_AUTO_CREATE);

当应用程序绑定一个Service后,该应用程序和Service之间就能进行互相通信,通常,这种通信的完成依靠于我们定义的一些接口,请看下例:

package com.wissen.testApp;

public interface IMyService {
public int getStatusCode();
}

这里定义了一个方法来获取Service的状态,但是Service是如何来使它起作用的呢?之前我们看到Service中有个返回IBinder对象的 onBind方法,这个方法会在Service被绑定到其他程序上时被调用,而这个IBinder对象和之前看到的onServiceConnected 方法中传入的那个IBinder是同一个东西。应用和Service间就依靠这个IBinder对象进行通信: public class MyService extends Service {
private int statusCode;
private MyServiceBinder myServiceBinder = new MyServiceBinder();

@Override
public IBinder onBind(Intent intent) {
return myServiceBinder;
} public class MyServiceBinder extends Binder implements IMyService {
public int getStatusCode() {
return statusCode;
}
}


} 下列代码是说明getStatusCode是如何被调用的: ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyService myService = (IMyService) service;
statusCode = myService.getStatusCode();
Log.i(”INFO”, “Service bound “);
}


};

或者,你也可以通过使用ServiceListener接口来达成相同的目的。

与远程Service通信(进程间Service通信):
如何两个进程间的Service需要进行通信,则需要把对象序列化后进行互相发送。
Android提供了一个 AIDL (Android接口定义语言)工具来处理序列化和通信。这种情况下Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。Service的实现类需要去继承这个 stub服务桩类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:
先创建一个IMyRemoteService.aidl文件,内容如下:

package com.wissen.testApp;

interface IMyRemoteService {
int getStatusCode();
}

如果你正在使用eclipse的 Android插件,则它会根据这个aidl文件生成一个Java接口类。生成的接口类中会有一个内部类Stub类,你要做的事就是去继承该Stub类:

package com.wissen.testApp;

class RemoteService implements Service {
int statusCode;

@Override
public IBinder onBind(Intent arg0) {
return myRemoteServiceStub;
}

private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
public int getStatusCode() throws RemoteException {
return 0;
}
};


}

当客户端应用连接到这个Service时,onServiceConnected方法将被调用,客户端就可以获得IBinder对象。参看下面的客户端onServiceConnected方法:


ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyRemoteService myRemoteService = IMyRemoteService.Stub.asInterface(service);
try {
statusCode = myRemoteService.getStatusCode();
} catch(RemoteException e) {
// handle exception
}
Log.i(”INFO”, “Service bound “);
}


};

权限:
我们可以在AndroidManifest.xml文件中使用<service>标签来指定Service访问的权限:

<service class=”.service.MyService” android:permission=”com.wissen.permission.MY_SERVICE_PERMISSION”>
<intent-filter>
<action android:value=”com.wissen.testApp.service.MY_SERVICE” />
</intent-filter>
</service>

之后应用程序要访问该Service的话就需要使用<user-permission>标签来指定相应的权限:

<uses-permission android:name=”com.wissen.permission.MY_SERVICE_PERMISSION”>
</uses-permission>

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. Android中LCD背光驱动
  5. Android换行符变成方框的解决方法
  6. Service 详解
  7. Android(安卓)onTouchEvent, onClick及onLongClick的调用机制
  8. Android(安卓)onTouchEvent, onClick及onLongClick的调用机制
  9. 如何看待 Kotlin 成为 Android(安卓)官方支持开发语言?

随机推荐

  1. Android(安卓)图片的浏览、缩放、拖动和
  2. android-screenshot-library - Library f
  3. android部署运行已有项目小结
  4. android 启动页面
  5. Android(安卓)apk打包流程,AAPT打包,apk瘦
  6. Android(安卓)StageFrightMediaScanner源
  7. adb命令
  8. Android中文API(130) —— Html
  9. [置顶] android 学习连接 uri
  10. Android(安卓)version and Linux Kernel