用一个MP3播放应用来体会Android中的Service

本文详细介绍了Android中的Service概念及其生命周期,包括Service的创建、启动、通信及优先级调整等,并通过一个简单的MP3播放示例展示了Service的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=large]
手机是人们生活中不可或缺的一个有用工具。我们在使用手机时,往往是多线程的,而且是会突然间断的。比如我们会一边浏览网页,一边听MP3。或者正在发短信的时候,突然打进来电话。这样我们必定会离开当前的用户界面。比如你会关闭MP3歌曲列表,去发短信,所以往往就需要有些程序在后台完成,暂时脱离屏幕。这时就可以用到Android中的Service
下面会用一个播放MP3的小应用来体会一下Android的Service
[/size]

[b]什么是Service[/b]
Android引入了Service的概念是为了处理后台进程。Service不实现任何用户界面。最常见的例子如:媒体播放器程序,它可以在转到后台运行的时候仍然能保持播放歌曲;或者如文件下载程序,它可以在后台执行文件的下载。
它跟Activity的级别差不多,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。

[b]Service的生命周期[/b]
Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy
我们有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。两种启动Service的方式有所不同。这里要说明一下的是如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。

[b]创建一个Service[/b]
Android中已经定义了一个 ‘Service’类,所有其他的Service都继承于该类。Service类中定义了一系列的生命周期相关的方法,如: onCreate(), onStart(), onDestroy()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
长期推荐成都知名外企(英语好 C++ JAVA)
mail to:hot13399@163.com
[url]http://woshizn.iteye.com/blog/1195498[/url]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[b]启动Service[/b]
有了 Service 类我们如何启动他呢,有两种方法:
Context.startService()
Context.bindService()
在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。
另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。

[b]用其他方式启动 Service[/b]
其实不光能从 Activity 中启动 Service ,还有一个很有用的方法是接收系统的广播,这就要用到 Receiver 。在 Mainfest 文件中配置你得 Receiver 能接收什么样的广播消息,那么即使你得程序没有显示给用户,你的 Service 也能启动。你要做的就是继承 android.content.BroadcastReceiver ,然后实现 onReceive(Context context, Intent intent) 方法,就可以启动你得 Service 了。这里不能 bindService 因为一个 Receiver 是一个短暂存在的对象,所以 bind 是没有什么意义的。

[b]与 Service 通信并且让它持续运行[/b]
如果我们想保持和 Service 的通信,又不想让 Service 随着 Activity 退出而退出呢?
可以先 startService() 再 bindService()。当不需要绑定的时候再执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。

[b]提高 Service 优先级[/b]
Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运行,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。
为什么是 foreground ? 默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。

MP3TestActivity.java提供控制界面

package com.android.mp3test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MP3TestActivity extends Activity {

private Button start;
private Button stop;
private Intent i;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) this.findViewById(R.id.start);
stop = (Button) this.findViewById(R.id.stop);

// 指向MP3播放Service的action
i = new Intent("com.kennan.android.music");

start.setOnClickListener(startListener);
stop.setOnClickListener(stopListener);

}

private OnClickListener startListener = new OnClickListener() {

public void onClick(View v) {
// 开始服务
MP3TestActivity.this.startService(i);
}

};

private OnClickListener stopListener = new OnClickListener() {

public void onClick(View v) {
// 结束服务
MP3TestActivity.this.stopService(i);
}
};
}


MusicService.java提供MP3播放功能,在开启播放后,可以尝试退出应用程序界面。看是否音乐还在继续播放。


package com.android.mp3test;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;

public class MusicService extends Service {

private MediaPlayer player;

public IBinder onBind(Intent arg0) {
return null;
}

public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// 在服务开始时,启动MP3播放
player = MediaPlayer.create(this, R.raw.music);
player.start();
}

public void onDestroy() {
// 在服务消灭时,关闭MP3播放
player.stop();
super.onDestroy();
}
}



layout/mean.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>

<Button android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start"
/>
<Button android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stop"
/>

</LinearLayout>



AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.mp3test" android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MP3TestActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service android:name="MusicService">
<intent-filter>
<action android:name="com.kennan.android.music" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
</application>
<uses-sdk android:minSdkVersion="4" />

</manifest>


参考项目结构
[img]http://dl.iteye.com/upload/attachment/204120/f4f1c0c8-8249-364c-a533-749134b8a035.png[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值