- 浏览: 625999 次
文章分类
最新评论
-
q781253433:
qin ~.求demo看看~
Android之Widget -
zhongyuanceshi:
博主,没看到你的例子的Demo,共享下
Android之Widget
引用:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html
Service是android 系统中的一种组件,它跟Activity的级别差不多,但是他不能自己运行,只能后台运行,并且可以和其他组件进行交互。Service的启动有两种方式:
context.startService()
和
context.
bindService()。
使用
context.
startService() 启动Service是会会经历:
context.startService() ->onCreate()- >onStart()->Service running
context.stopService() | ->onDestroy() ->Service stop
如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。
stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。
所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy
使用使用
context
.bindService()启动Service会经历:
context
.bindService()->onCreate()->onBind()
->Service running
onUnbind() ->
onDestroy() ->Service stop
onBind
将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者
(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用
onUnbind->onDestroy相应退出。
所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。
service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。
下面我做了一个简单的音乐播放的应用,分别使用startService和bindService来启动本地的服务。
而在下一篇《
android service 学习(下)
》会介绍通过AIDL对Service进行远程调用。
下面是整个应用启动界面:
先从使用startService启动Service学起
首先编写一个
Activity
01
|
public
class
PlayMusic
extends
Activity
implements
OnClickListener {
|
02
|
private
static
final
String TAG =
"PlayMusic"
;
|
03
|
private
Button playBtn;
|
04
|
private
Button stopBtn;
|
05
|
private
Button pauseBtn;
|
06
|
private
Button exitBtn;
|
07
|
private
Button closeBtn;
|
08
|
09
|
//....(详见源码)
|
10
|
11
|
@Override
|
12
|
public
void
onClick(View v) {
|
13
|
int
op = -
1
;
|
14
|
Intent intent =
new
Intent(
"org.allin.android.musicService"
);
|
15
|
|
16
|
//广播用
|
17
|
// Intent intent = new Intent("org.allin.android.musicReceiver");
|
18
|
|
19
|
switch
(v.getId()) {
|
20
|
case
R.id.play:
|
21
|
Log.d(TAG,
"onClick: playing muic"
);
|
22
|
op =
1
;
|
23
|
break
;
|
24
|
case
R.id.stop:
|
25
|
Log.d(TAG,
"onClick: stoping music"
);
|
26
|
op =
2
;
|
27
|
break
;
|
28
|
case
R.id.pause:
|
29
|
Log.d(TAG,
"onClick: pausing music"
);
|
30
|
op =
3
;
|
31
|
break
;
|
32
|
case
R.id.close:
|
33
|
Log.d(TAG,
"onClick: close"
);
|
34
|
this
.finish();
|
35
|
break
;
|
36
|
case
R.id.exit:
|
37
|
Log.d(TAG,
"onClick: exit"
);
|
38
|
op =
4
;
|
39
|
stopService(intent);
|
40
|
this
.finish();
|
41
|
break
;
|
42
|
}
|
43
|
|
44
|
Bundle bundle =
new
Bundle();
|
45
|
bundle.putInt(
"op"
, op);
|
46
|
intent.putExtras(bundle);
|
47
|
startService(intent);
|
48
|
|
49
|
// sendBroadcast(intent);
|
50
|
}
|
51
|
52
|
53
|
}
|
通过重写
onClick方法来实现对播放音乐的控制。这里把播放音乐的各种操作用数字的方式通过Intent传递给service。
构造一个Intent ,ntent intent = new Intent("org.allin.android.musicService");
"org.allin.android.musicService"是在AndroidManifest.xml文件中对service类的定义
1
|
<service android:enabled=
"true"
android:name=
".MusicService"
>
|
2
|
<intent-filter>
|
3
|
<action android:name=
"org.allin.android.musicService"
/>
|
4
|
</intent-filter>
|
5
|
</service>
|
把操作码放在
Bundle中
Bundle bundle = new Bundle();
bundle.putInt("op", op);
intent.putExtras(bundle);
最后使用startService(intent);启动服务。
下面看看Service是怎么实现的。
MusicService.java
01
|
/**
|
02
|
* @author allin.dev
|
04
|
*
|
05
|
*/
|
06
|
public
class
MusicService
extends
Service {
|
07
|
08
|
private
static
final
String TAG =
"MyService"
;
|
09
|
private
MediaPlayer mediaPlayer;
|
10
|
11
|
/*
|
12
|
* (non-Javadoc)
|
13
|
*
|
14
|
* @see android.app.Service#onBind(android.content.Intent)
|
15
|
*/
|
16
|
@Override
|
17
|
public
IBinder onBind(Intent arg0) {
|
18
|
return
null
;
|
19
|
}
|
20
|
21
|
@Override
|
22
|
public
void
onCreate() {
|
23
|
Log.v(TAG,
"onCreate"
);
|
24
|
if
(mediaPlayer ==
null
) {
|
25
|
mediaPlayer = MediaPlayer.create(
this
, R.raw.tmp);
|
26
|
mediaPlayer.setLooping(
false
);
|
27
|
}
|
28
|
}
|
29
|
30
|
@Override
|
31
|
public
void
onDestroy() {
|
32
|
Log.v(TAG,
"onDestroy"
);
|
33
|
if
(mediaPlayer !=
null
) {
|
34
|
mediaPlayer.stop();
|
35
|
mediaPlayer.release();
|
36
|
}
|
37
|
}
|
38
|
39
|
@Override
|
40
|
public
void
onStart(Intent intent,
int
startId) {
|
41
|
Log.v(TAG,
"onStart"
);
|
42
|
if
(intent !=
null
) {
|
43
|
Bundle bundle = intent.getExtras();
|
44
|
if
(bundle !=
null
) {
|
45
|
46
|
int
op = bundle.getInt(
"op"
);
|
47
|
switch
(op) {
|
48
|
case
1
:
|
49
|
play();
|
50
|
break
;
|
51
|
case
2
:
|
52
|
stop();
|
53
|
break
;
|
54
|
case
3
:
|
55
|
pause();
|
56
|
break
;
|
57
|
}
|
58
|
59
|
}
|
60
|
}
|
61
|
62
|
}
|
63
|
64
|
public
void
play() {
|
65
|
if
(!mediaPlayer.isPlaying()) {
|
66
|
mediaPlayer.start();
|
67
|
}
|
68
|
}
|
69
|
70
|
public
void
pause() {
|
71
|
if
(mediaPlayer !=
null
&& mediaPlayer.isPlaying()) {
|
72
|
mediaPlayer.pause();
|
73
|
}
|
74
|
}
|
75
|
76
|
public
void
stop() {
|
77
|
if
(mediaPlayer !=
null
) {
|
78
|
mediaPlayer.stop();
|
79
|
try
{
|
80
|
// 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数
|
81
|
mediaPlayer.prepare();
|
82
|
}
catch
(IOException ex) {
|
83
|
ex.printStackTrace();
|
84
|
}
|
85
|
}
|
86
|
}
|
87
|
88
|
}
|
服务 使用了系统自带
MediaPlayer进行音乐的播放控制。 当调用了startService后服务会先调用onCreate,我们在里面对MediaPlayer进行初始化。接着会调用onStart,可以看到
传递给startService()的Intent对象会传递给onStart()方法,这样我们就可以得到intent里面的操作码:
Iundle bundle = intent.getExtras();
int op = bundle.getInt("op");
然后更具定义好的操作码进行相应的f播放操作。启动后界面如下图:
图中的”close”和“exit”是不同的,close只是调用
finish()退出当前的Activity,但是Service并没有关掉,音乐会继续播放。而exit就是调用了stopService(intent);来停止服务,Service会调用onDestroy()方法来对mediaPlayer进行停止和释放资源。
有时候如果服务只提供一些操作接口,我们也可以通过广播的g方式来启动服务。
首先要定义一个Receiver,并继承BroadcastReceiver,然后在AndroidManifest.xml中进行注册:
1
|
<receiver android:name=
".MusicReceiver"
>
|
2
|
<intent-filter>
|
3
|
<action android:name=
"org.allin.android.musicReceiver"
/>
|
4
|
</intent-filter>
|
5
|
</receiver>
|
Receiver的实现:
MusicReceiver.java
01
|
/**
|
02
|
* @author allin.dev
|
04
|
*
|
05
|
*/
|
06
|
public
class
MusicReceiver
extends
BroadcastReceiver {
|
07
|
08
|
private
static
final
String TAG =
"MusicReceiver"
;
|
09
|
@Override
|
10
|
public
void
onReceive(Context context, Intent intent) {
|
11
|
Log.d(TAG,
"onReceive"
);
|
12
|
Intent it =
new
Intent(
"org.allin.android.musicService"
);
|
13
|
Bundle bundle = intent.getExtras();
|
14
|
it.putExtras(bundle);
|
15
|
|
16
|
if
(bundle !=
null
){
|
17
|
int
op = bundle.getInt(
"op"
);
|
18
|
if
(op ==
4
){
|
19
|
context.stopService(it);
|
20
|
}
else
{
|
21
|
context.startService(it);
|
22
|
}
|
23
|
}
|
24
|
|
25
|
}
|
26
|
27
|
}
|
然后对
PlayMusic中的onclick方法进行些改造,把Intent指向Receiver
Intent intent = new Intent("org.allin.android.musicReceiver");
intent中绑定的操作码都不变,
再调用
sendBroadcast(intent);把intentg广播出去。
当
MusicReceiver接受到广播后根据操作码进行相应的操作。
接下来的例子就是使用
bindService来启动Service
首先一样是写一个
Activity
01
|
public
class
PlayBindMusic
extends
Activity
implements
OnClickListener {
|
02
|
03
|
private
static
final
String TAG =
"PlayBindMusic"
;
|
04
|
private
Button playBtn;
|
05
|
private
Button stopBtn;
|
06
|
private
Button pauseBtn;
|
07
|
private
Button exitBtn;
|
08
|
|
09
|
private
BindMusicService musicService;
|
10
|
11
|
@Override
|
12
|
public
void
onClick(View v) {
|
13
|
14
|
switch
(v.getId()) {
|
15
|
case
R.id.play:
|
16
|
Log.d(TAG,
"onClick: binding srvice"
);
|
17
|
musicService.play();
|
18
|
break
;
|
19
|
case
R.id.stop:
|
20
|
Log.d(TAG,
"onClick: stoping srvice"
);
|
21
|
if
(musicService !=
null
){
|
22
|
musicService.stop();
|
23
|
}
|
24
|
break
;
|
25
|
case
R.id.pause:
|
26
|
Log.d(TAG,
"onClick: pausing srvice"
);
|
27
|
if
(musicService !=
null
){
|
28
|
musicService.pause();
|
29
|
}
|
30
|
break
;
|
31
|
case
R.id.exit:
|
32
|
Log.d(TAG,
"onClick: exit"
);
|
33
|
this
.finish();
|
34
|
break
;
|
35
|
}
|
36
|
}
|
37
|
38
|
39
|
private
void
connection(){
|
40
|
Log.d(TAG,
"connecting....."
);
|
41
|
Intent intent =
new
Intent(
"org.allin.android.bindService"
);
|
42
|
bindService(intent, sc, Context.BIND_AUTO_CREATE);
|
43
|
|
44
|
}
|
45
|
private
ServiceConnection sc =
new
ServiceConnection() {
|
46
|
@Override
|
47
|
public
void
onServiceDisconnected(ComponentName name) {
|
48
|
musicService =
null
;
|
49
|
Log.d(TAG,
"in onServiceDisconnected"
);
|
50
|
}
|
51
|
|
52
|
@Override
|
53
|
public
void
onServiceConnected(ComponentName name, IBinder service) {
|
54
|
musicService = ((BindMusicService.MyBinder)(service)).getService();
|
55
|
if
(musicService !=
null
){
|
56
|
musicService.play();
|
57
|
}
|
58
|
|
59
|
Log.d(TAG,
"in onServiceConnected"
);
|
60
|
}
|
61
|
};
|
62
|
}
|
这里使用了bindService(intent, sc, Context.BIND_AUTO_CREATE);来启动服务的,
我们需要定义ServiceConnectionnn,并实现里面的方法,当服务绑定成功后会调用ServiceConnectionnn中的回调函数:
public void onServiceConnected(ComponentName name, IBinder service),
回
调函数里面使用musicService =
((BindMusicService.MyBinder)(service)).getService();来获取BindMusicService服
务对象,有了BindMusicService实例对象,就可以调用服务提供的各种控制音乐播放的哦功能。
下面看看BindMusicService.java的实现:
01
|
/**
|
02
|
* @author allin.dev
|
04
|
*/
|
05
|
public
class
BindMusicService
extends
Service {
|
06
|
07
|
private
static
final
String TAG =
"MyService"
;
|
08
|
private
MediaPlayer mediaPlayer;
|
09
|
10
|
private
final
IBinder binder =
new
MyBinder();
|
11
|
12
|
public
class
MyBinder
extends
Binder {
|
13
|
BindMusicService getService() {
|
14
|
return
BindMusicService.
this
;
|
15
|
}
|
16
|
}
|
17
|
18
|
/*
|
19
|
* (non-Javadoc)
|
20
|
*
|
21
|
* @see android.app.Service#onBind(android.content.Intent)
|
22
|
*/
|
23
|
@Override
|
24
|
public
IBinder onBind(Intent intent) {
|
25
|
Log.d(TAG,
"onBind"
);
|
26
|
play();
|
27
|
return
binder;
|
28
|
}
|
29
|
30
|
@Override
|
31
|
public
void
onCreate() {
|
32
|
super
.onCreate();
|
33
|
|
34
|
Log.d(TAG,
"onCreate"
);
|
35
|
Toast.makeText(
this
,
"show media player"
, Toast.LENGTH_SHORT).show();
|
36
|
|
37
|
|
38
|
}
|
39
|
40
|
@Override
|
41
|
public
void
onDestroy() {
|
42
|
super
.onDestroy();
|
43
|
|
44
|
Log.d(TAG,
"onDestroy"
);
|
45
|
Toast.makeText(
this
,
"stop media player"
, Toast.LENGTH_SHORT);
|
46
|
if
(mediaPlayer !=
null
){
|
47
|
mediaPlayer.stop();
|
48
|
mediaPlayer.release();
|
49
|
}
|
50
|
}
|
51
|
52
|
|
53
|
public
void
play() {
|
54
|
if
(mediaPlayer ==
null
) {
|
55
|
mediaPlayer = MediaPlayer.create(
this
, R.raw.tmp);
|
56
|
mediaPlayer.setLooping(
false
);
|
57
|
}
|
58
|
if
(!mediaPlayer.isPlaying()) {
|
59
|
mediaPlayer.start();
|
60
|
}
|
61
|
}
|
62
|
63
|
public
void
pause() {
|
64
|
if
(mediaPlayer !=
null
&& mediaPlayer.isPlaying()) {
|
65
|
mediaPlayer.pause();
|
66
|
}
|
67
|
}
|
68
|
69
|
public
void
stop() {
|
70
|
if
(mediaPlayer !=
null
) {
|
71
|
mediaPlayer.stop();
|
72
|
try
{
|
73
|
// 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数
|
74
|
mediaPlayer.prepare();
|
75
|
}
catch
(IOException ex) {
|
76
|
ex.printStackTrace();
|
77
|
}
|
78
|
}
|
79
|
}
|
80
|
81
|
}
|
我
们看到Service中有个返回IBinder对象的onBind方法,这个方法会在Service被绑定到其他程序上时被调用,而这个IBinder对
象和之前看到的onServiceConnected方法中传入的那个IBinder是同一个东西。应用和Service间就依靠这个IBinder对象
进行通信。
启动后的界面如下图:
发表评论
-
Android之Fastboot、Recovery基础知识
2013-12-19 22:13 1078参考文章: http://blog.csdn.net/y9 ... -
Eclipse设置主题
2013-10-26 22:32 698下载自己喜欢的主题: http://eclipsec ... -
gitignore文件的配置
2013-09-24 15:29 1730gitignore文件在Android ... -
Eclipse安装Git插件
2013-09-24 14:20 804http://jiangli.easymorse.com/?p ... -
Eclipse像Xcode一样自动有提示
2013-09-05 17:04 12201. 打开Eclipse,然后打开“Preferences ... -
点九PNG技术
2013-04-16 13:26 886参考文章: http://blog.csdn.net/g ... -
Android ASE 脚本环境
2013-04-10 12:32 1187原文: http://blog.sina.com.cn/ ... -
android 按两次返回键退出
2012-12-25 20:01 1322package com.anjoyo.test; ... -
android混淆代码总结
2012-12-19 18:02 1523反编译工具下载地址:http://ishare.iask.si ... -
System.out.printf输出格式
2012-12-13 22:01 2527// 定义一些变量,用来格式化输出。 double ... -
Regex正则表达式的使用
2012-12-09 20:20 1831正则表达式是用来描述某些字符串规则的工具,可以用此规则来做 ... -
IOS&Android开发 使用特殊字体,使用自定义字体
2012-11-24 00:16 1570IOS开发: 原文链接:http://tieba.baidu ... -
AspectJ的安装和Eclipse的AJDT插件的配置
2012-11-19 15:21 4960安装AspectJ是为了正常使用软件MonkeyTalk 1 ... -
Mac配置android开发环境
2012-11-13 16:18 48一.Eclipse的下载 到网站:http ... -
RelativeLayout相关属性
2012-11-13 14:49 962android:layout_centerInP ... -
Android资源文件
2012-11-04 15:22 992res [res中共有10种文 ... -
activity的启动方式(launch mode)
2012-11-04 15:14 866其他很详细的参考:http://blog.csdn.net/b ... -
android分享功能的实现(分享到微博空间等)
2012-11-03 22:15 2210//Intent intent = new Inten ... -
Android开发环境配置
2012-11-03 20:04 8821、JDK安装: http://jing ... -
android intent和intent action大全
2012-09-13 20:25 1059android 中intent是经常要用到的。不管是页面 ...
相关推荐
### Android Service 学习(下): 进程间通信与 AIDL 在深入探讨 Android Service 的高级用法时,我们不可避免地会接触到进程间通信(IPC)这一关键概念。由于 Android 应用程序通常在各自独立的进程中运行,因此它们...
这是Pro Android学习系列中Android Service部分的例子源代码。相关学习笔记见:http://blog.csdn.net/flowingflying/article/details/6212512
本篇文章将深入探讨“android学习之Service启动1”的主题,主要关注Service的启动方式及其基本用法。 首先,Service有两种启动模式:startService()和bindService()。`startService()`主要用于启动一个无需与调用者...
在《android service 学习笔记(下)》中,会介绍如何通过AIDL(Android Interface Definition Language)实现对Service的远程调用,这允许不同进程间的组件通信,增强了Service的功能和使用范围。 总结来说,...
本案例“android音乐播放器service学习案例”着重讲解如何利用Service来实现一个音乐播放器,使音乐能够在后台持续播放。 首先,我们需要了解Android Service的基础知识。Service分为两种类型:标准服务...
在Android开发中,Service是应用组件之一,它可以在后台长时间运行,即使用户界面...通过“android service toast 01”这个项目,开发者可以深入学习Android后台服务的使用,以及如何在非主线程中正确地更新用户界面。
### Android学习之Service开机启动详解 #### 一、引言 在Android开发中,有时我们需要让应用程序中的某个服务(Service)在设备启动时自动运行,例如进行后台数据同步、监控某些变化等。为了实现这一需求,可以...
在"android中service组件自我学习练习"中,我们可能涉及到以下几个关键知识点: 1. **Service的声明**:在AndroidManifest.xml文件中,需要声明Service组件,指定其类名,以便系统能够识别和加载。 2. **Service的...
学习这个实例,开发者可以理解Service的运作机制,如何在实际项目中应用Service,以及如何处理Service与Activity之间的通信。这对于构建高效、稳定的Android应用至关重要,特别是对于那些需要在后台持续运行的任务。...
提到的"Exercise"可能是练习文件或者代码示例,通常在学习Service时,开发者会创建一个简单的Service项目,模拟启动Service,然后在另一个Activity中控制Service的启动和停止,或者绑定和解绑,以加深理解。...
在Android应用开发中,...通过学习和实践这个Demo,开发者可以更好地理解和掌握Android中Service和AIDL的使用,提升应用的扩展性和功能。在开发过程中,合理运用Service和AIDL可以实现复杂的应用架构,提高用户体验。
综上所述,"android service下载资源,同时解压资源"这一功能实现涉及到了Android Service、异步下载、BroadcastReceiver、ZIP文件解压等多个技术点,这些知识点在实际的Android应用开发中都非常常见且重要。...
本篇将详细介绍Android Service的源码学习及其关键知识点。 首先,我们来了解Service的基本生命周期。在Android中,Service的启动与绑定是通过`startService()`和`bindService()`方法完成的。当调用`startService()...
在Android应用开发中,`Service` 是...综上所述,"Android学习之Service练习"涵盖了Android开发中不可或缺的一部分,通过实际操作,你可以更好地理解Service的工作原理和使用场景,为开发更复杂的应用打下坚实的基础。
在Android应用开发中,Service是四大组件之一,用于在后台长时间运行操作,比如播放音乐、网络通信等。然而,如果不加以控制,...通过学习和实践,你将能够更好地掌握Android Service的管理和控制,提高你的应用质量。
通过深入学习Service的源码,结合各种工具进行调试和分析,开发者可以更高效地利用Service实现复杂的功能,同时确保应用的稳定性和性能。在实际开发中,务必注意Service的生命周期管理,避免不必要的资源浪费,提升...
在Android应用开发中,Service是一种在后台运行的组件,它不具有用户界面,但可以执行长时间的任务或与其他组件进行通信。在某些情况下,我们可能需要一个Service去执行一些任务,并在任务完成后更新UI。这时,我们...