今天重新学习一下android service的用法,service在一般的应用开发中比较常见,比如:应用商店的apk下载,播放音乐等。
1. service简介
service到底是个神马东西呢?根据官网文档的描述可以得知,service是android系统的一个应用组件,启动之后一直默默的长时间的运行在后台,不像activty那样可以跟用户交互,就算我们退出应用了,service仍然可以在后台执行。因此可以利用service的这个特性帮我们解决很多问题,想熟练使用service就得先了解它的生命周期。service可分为两种:本地服务和远程服务,本篇只介绍本地服务,下一篇介绍远程服务,实现跨进程通信(IPC)。
2.service生命周期及本地Service的使用
service可以通过两种方式创建:startService()和bindService().
startService():一般用于在后台上传文件或者下载文件等,不跟其他组件通信,就算启动它的应用被销毁了,它仍然会欢快的在后台执行,直到完成任务的时候自刎(自己调用stopSelf())或者被其他人下黑手(调用stopService()).
bindService():允许其他组件跟它进行通信,允许多个客户端绑定到同一个service上,当所有的客户端都解除绑定后,该service就销毁了。
service的生命周期主要是跟这4个回调函数相关,onCreate()、onStartCommend()、onBind()、onDestory(),首先看看下面这张图,然后结合下面的demo,就很容易理解了。
下面通过一个简单demo看看分别通过两种方式启动service时,这些回调函数的执行过程。
(1)startService()
新建一个StartLocalServiceActivity.java文件,定义两个按钮用来启动和停止service
package com.alexzhou.servicedemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* 启动一个本地Service
*
* @author alexzhou
*/
public class StartLocalServiceActivity extends Activity implements
OnClickListener {
private Button startButton;
private Button stopButton;
private final String LOCAL_START_SERVICE_ACTION = "com.alexzhou.service.LOCAL_START_SERVICE";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_local_service);
findViews();
setListeners();
}
private void findViews() {
startButton = (Button) this.findViewById(R.id.start);
stopButton = (Button) this.findViewById(R.id.stop);
}
private void setListeners() {
startButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
this.startService(new Intent(LOCAL_START_SERVICE_ACTION));
break;
case R.id.stop:
this.stopService(new Intent(LOCAL_START_SERVICE_ACTION));
break;
}
}
}
新建一个LocalService.java文件,这个就是本地service文件。
package com.alexzhou.servicedemo.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
/**
* 本地服务
* @author alexzhou
*/
public class LocalService extends Service {
private final String TAG = LocalService.class.getSimpleName();
private LocalBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public LocalService getService() {
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return mBinder;
}
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
}
public String getContent() {
return "welcome access local service!";
}
}
AndroidManifest.xml添加
<activity android:name=".StartLocalServiceActivity" />
<activity android:name=".BindLocalServiceActivity" />
<service
android:name=".service.LocalService"
android:exported="false" >
<intent-filter>
<action android:name="com.alexzhou.service.LOCAL_BIND_SERVICE" />
<action android:name="com.alexzhou.service.LOCAL_START_SERVICE" />
</intent-filter>
</service>
考虑到篇幅问题,布局文件就不贴出来了,点击屏幕上的启动服务按钮,看看Logcat的输出信息:会依次打印出onCreate()->onStartCommand().
点击停止服务按钮,此时会执行:onDestory()方法销毁service。
onCreate()方法在service第一次创建的时候会调用,如果该service已经运行了则不会执行该函数。
onStartCommand()方法是在其他组件通过调用startService()启动服务时才会执行。每次启动service时,onStartCommand()都会被执行。你多点几次启动服务按钮,会看到每次都会执行onStartCommand()。
(2) bindService()
创建一个BindLocalServiceActivity.java文件,也同样弄两个button来绑定和解绑服务。
package com.alexzhou.servicedemo;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.alexzhou.servicedemo.service.LocalService;
/**
* 绑定一个本地Service
*
* @author alexzhou
*/
public class BindLocalServiceActivity extends Activity implements
OnClickListener {
private TextView callbackView;
private Button bindButton;
private Button unbindButton;
private boolean isBind;
private final String LOCAL_BIIND_SERVICE_ACTION = "com.alexzhou.service.LOCAL_BIND_SERVICE";
private LocalService mLocalService = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bind_local_service);
findViews();
setListeners();
callbackView.setText("Not attached.");
}
private void findViews() {
callbackView = (TextView) this.findViewById(R.id.callback);
bindButton = (Button) this.findViewById(R.id.bind);
unbindButton = (Button) this.findViewById(R.id.unbind);
}
private void setListeners() {
bindButton.setOnClickListener(this);
unbindButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bind:
this.bindService(new Intent(LOCAL_BIIND_SERVICE_ACTION),
mConntectin, Context.BIND_AUTO_CREATE);
isBind = true;
callbackView.setText("binding...");
break;
case R.id.unbind: {
if (isBind) {
this.unbindService(mConntectin);
isBind = false;
callbackView.setText("unbind...");
}
}
break;
}
}
private ServiceConnection mConntectin = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.i(BindLocalServiceActivity.class.getSimpleName(),
"onServiceDisConnected");
callbackView.setText("Disconnected!");
Toast.makeText(BindLocalServiceActivity.this,
R.string.remote_service_disconntected, Toast.LENGTH_SHORT)
.show();
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.i(BindLocalServiceActivity.class.getSimpleName(),
"onServiceConnected");
mLocalService = ((LocalService.LocalBinder) binder).getService();
callbackView.setText("attached!" + mLocalService.getContent());
Toast.makeText(BindLocalServiceActivity.this,
R.string.remote_service_connected, Toast.LENGTH_SHORT)
.show();
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (isBind) {
this.unbindService(mConntectin);
isBind = false;
}
}
}
点击绑定服务按钮,从Logcat输出的信息中可以看出调用顺序:onCreate()->onBind() ->onServiceConnnected()
同理onCreate()只会在service第一次创建时执行。
点击解绑服务,会调用service的onDestory()方法。可以先调用startService(),然后再绑定该service,这样解除绑定的时候service就不会被销毁了,需要unbindService()和stopService()都调用,服务才会销毁。注意:连接正常关闭的情况下,上述代码中onServiceDisconnected是不会调用的,只有在异常关闭的时候调用,比如被kill了。
3. service和线程的区别
刚开始接触service的时候,很多人会有这样的疑问,为什么不用thread代替service呢。首先得明白本地service是运行在主进程的main线程上的,如果是远程service,则运行在独立进程的main线程上。而新建线程主要是用来执行一些异步的操作。首先从生命周期来分析,当一个应用程序被强制终止后,应用程序中开启的线程也会被销毁,而service可以做到在应用被终止的情况下仍然在后台欢快的运行。其次是同一个线程对象没法被多个activty控制,如有时候会出现这种情况:当 Activity 被 finish
之后,该Activty启动的线程还在执行,此时你失去了对该线程的引用,只能通过终止应用来停止该线程的运行。对于一些比较关键的服务,一般选择使用service,如果比较耗时则可以在service中创建和控制线程,进行异步操作。
转载请注明来自:Alex
Zhou,本文链接:http://codingnow.cn/android/515.html
分享到:
相关推荐
android Service的生命周期 bind以及startService两种方式 对应的生命周期
Activity和Service生命周期及使用AIDL通信
Android说明Service生命周期的代码例子。用于演示Service组件从创建到销毁的完整生命周期,以及IntentService的使用例子。
startService启动方式,只在activity中启动和销毁,和activity关系不大,即使antivity退出,服务任然运行,比如后台放音乐,对应生命周期: bindService启动方式,和activity绑定后,和activity共存亡,activity...
非常简单明了的 android java 层的 service分析。
组件生命周期将讨论活动、服务、广播接收者的生命周期——包括在生命周期中他们可能的状态、通知状态改变 的方法、及这些状态的组件寄宿的进程被终结和实例被销毁的可能性。 上篇Android开发之旅:组件生命周期(一...
AndroidService生命周期及用法[收集].pdf
Service概念及用途: Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那...Service生命周期 : Android
android项目教程Service生命周期.pptx
一个小demo,通过求平均值,测试service的生命周期以及启动方式!
startService启动方式,只在activity中启动和销毁,和activity关系不大,即使antivity退出,服务任然运行,比如后台放音乐,对应生命周期: bindService启动方式,和activity绑定后,和activity共存亡,activity...
Android中Service生命周期演示案例的任务要求.pdf 学习资料 复习资料 教学资源
android 生命周期,service演示, 透明背景设置,android界面切换演示
Android中演示Service生命周期的代码清单.pdf 学习资料 复习资料 教学资源
1.Service的类图和生命周期 先来看看Service的类图: 接下来看看Service的生命周期: 2.开发Service (1)开发Service需要两步: 第1步:定义子类,继承Service 第2步:在AndroidManifest.xml文件中配置...
项目视频介绍#标题视频地址1服务的生命周期视频12服务的生命周期视频23Android Service全面认识三
Android中Service的生命周期解析.pdf 学习资料 复习资料 教学资源
对于应用开发者来说,理解不同的应用组件(特别是Activity、Service、Intent Receiver)对应用进程的生命周期的影响,这是非常重要的。如果没有正确地使用这些组件,将会导致当应用正在处理重要的工作时,进程却被...