惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
K
Kaspersky official blog
L
LINUX DO - 热门话题
P
Proofpoint News Feed
P
Privacy & Cybersecurity Law Blog
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
Cisco Talos Blog
Cisco Talos Blog
AI
AI
L
LINUX DO - 最新话题
H
Heimdal Security Blog
Hacker News: Ask HN
Hacker News: Ask HN
Webroot Blog
Webroot Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The GitHub Blog
The GitHub Blog
I
Intezer
Blog — PlanetScale
Blog — PlanetScale
有赞技术团队
有赞技术团队
S
Securelist
博客园_首页
IT之家
IT之家
Schneier on Security
Schneier on Security
博客园 - 叶小钗
罗磊的独立博客
WordPress大学
WordPress大学
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
阮一峰的网络日志
阮一峰的网络日志
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
W
WeLiveSecurity
The Register - Security
The Register - Security
D
DataBreaches.Net
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
Recorded Future
Recorded Future
NISL@THU
NISL@THU
N
News and Events Feed by Topic
T
Tailwind CSS Blog
N
News and Events Feed by Topic
Cyberwarzone
Cyberwarzone
T
Tor Project blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com

博客园 - 和尚释然

AsyncTask原理 Android 模拟器截图 [原创]Android NDK开发之HelloWorld 附源码 Android NDK开发之环境搭建 [原创]深入了解Activity生命周期 附源码 [原创]Android Camera 开发之实现一 附源码 [原创]Android Camera 开发之前言 [原创]在Eclipse中手工安装SVN Plugin Android开发环境搭建四:新建一台Android Virtual Device Android开发环境搭建三:在Eclipse配置Android SDK Android开发环境搭建二:安装ADT[新版本ADT15.0] Android开发环境搭建一:安装Android JDK Java开发环境配置图解 用Reflector反编译 Mobile Winform程序 Mobile WiFi的开启和关闭代码实现 VS2005/VS2008英文版应用程序无法显示中文字符 深入讲解main()返回值研究 用VisualStudio2008汇编代码 发布MFC ActiveX控件并实现自动更新
[原创]关于Android Service的示例编程 附源码
和尚释然 · 2012-06-24 · via 博客园 - 和尚释然

2012-06-24 15:08  和尚释然  阅读(1505)  评论()    收藏  举报

关于Android Service的示例编程


一.什么是Android Service

大家知道如果要让Android程序在退出时还需要继续运行一些应用时,例如后台音乐播放,后台数据上传和下载等应用.这个时候可以使用Android Service来实现.网上有很多关于Android Service的介绍,我想最权威的应该是Android API文档的解释.

服务是运行在后台的一个程序组件,而且没有与用户交互接口.其他应用程序可以启动一个服务,而且服务可以继续在后台运行即使用户已经切换到其他应用程序.另外,程序还可以绑定一个服务与它交互,甚至还是进行IPC(Interprocess Communication).例如,服务可能需要处理网路传输,播放音乐,I/O操作,或者与一个内容提供者交互.所有的这些都是来自后台.

二.Android Service的实现

服务主要有以下两种形式:

1. Start

通过调用应用程序组件(例如Activity)的startService()方法来启动一个服务.一旦启动,服务就会在后台一直运行,即使应用程序组件此时被关闭.通常,已经启动的服务会处理一些单一功能,并且也不需要返回结果给调用者.例如,在网络上下载或上传文件.当服务的工作处理结束,才会自己关闭服务.

2. Bound

通过调用应用程序组件的bindService()方法来绑定一个服务.已绑定的服务会提供一个客户端-服务端交互接口.该接口主要用来与应用程序交互,发送请求,获取结果,甚至通过IPC来访问进程.只要一个程序组件绑定服务就会运行绑定服务,多个应用程序组件可以同时时间绑定一个服务.当所有的应用程序组件都解除绑定,该绑定服务器就会被销毁.

下面我们分别对"Started Service"和"Bound Servie"作一个介绍.

.创建Started Service

我觉得通过一个实例来介绍比文字说明更能说明知识点.同时也让开发者清楚地了解到创建一个"Started Service"的开发流程.实例是一个利用后台服务播放音乐的Demo,点击Start运行服务,点击Stop停止服务.

1. 创建一个"Android Project"名为"StatredServiceDemo".

2.创建界面元素.

3. 在Manifest里面声明服务,添加MyService声明.

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.gel.service"

    android:versionCode="1"

    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name" >

        <activity

            android:label="@string/app_name"

            android:name=".MainActivity" >

            <intent-filter >

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

       

 <service android:enabled="true" android:name=".MyService" />

    </application>

</manifest>

4. 添加一个MyService类.

实现代码:

public class MyService extends Service {

private static final String TAG = "MyService";

MediaPlayer player;

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return null;

}

@Override

public void onCreate() {

Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();

Log.i(TAG, "onCreate");

player = MediaPlayer.create(this, R.raw.ann);

player.setLooping(false);

super.onCreate();

}

@Override

public void onDestroy() {

Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();

Log.i(TAG, "onDestroy");

player.stop();

super.onDestroy();

}

@Override

public void onStart(Intent intent, int startid) {

Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();

Log.i(TAG, "onStart");

player.start();

}

}

5.MainActivity代码实现

public class MainActivity extends Activity implements OnClickListener {

private static final String TAG = "ServiceDemo";

Button buttonStart;

Button buttonStop;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

/*

 * TextView tv = (TextView)findViewById(R.id.tvTemp); tv.setText("测试");

 */

buttonStart = (Button) findViewById(R.id.btnStart);

buttonStop = (Button) findViewById(R.id.btnStop);

buttonStart.setOnClickListener(this);

buttonStop.setOnClickListener(this);

}

public void onClick(View src) {

switch (src.getId()) {

case R.id.btnStart:

Log.d(TAG, "onClick: starting srvice");

startService(new Intent(this, MyService.class));

break;

case R.id.btnStop:

Log.d(TAG, "onClick: stopping srvice");

stopService(new Intent(this, MyService.class));

break;

}

}

}

6.最后来看看运行效果.

日志输出:

注意:

从日志中我们可以看出

启动一个Service的过程如下:

context.startService()  ->onCreate()  ->onStart()->Service running

停止一个Service的过程如下:
context.stopService()  ->onDestroy() ->Service stop

四.创建Bound Service

Bound Service的创建是通过应用程序组件调用bindService()方法建立的.主要用于长时间连接应用.通常不允许通过调用startService()方法来启动.

创建一个Bound Service必须实现"onBind()"回调方法返回IBinder对象.IBinder用来定义与服务交互的接口.其他程序组件调用bindService()方法取得该接口同时可以调用服务提供的方法.

1. 创建一个Android Project名为"BoundServiceDemo".

 

2. 创建界面元素

3. 新建一个MyService类

MyService代码:

public class MyService extends Service {

// 定义个一个Tag标签

private static final String TAG = "MyService";

// 这里定义吧一个Binder类,用在onBind()有方法里,这样Activity那边可以获取到

private MyBinder mBinder = new MyBinder();

@Override

public IBinder onBind(Intent intent) {

Log.e(TAG, "Start IBinder!");

return mBinder;

}

@Override

public void onCreate() {

Log.e(TAG, "Start onCreate!");

super.onCreate();

}

@Override

public void onStart(Intent intent, int startId) {

Log.e(TAG, "Start onStart!");

super.onStart(intent, startId);

}

@Override

public void onDestroy() {

Log.e(TAG, "Start onDestroy!");

super.onDestroy();

}

@Override

public boolean onUnbind(Intent intent) {

Log.e(TAG, "Start onUnbind!");

return super.onUnbind(intent);

}

// 这里我写了一个获取当前时间的函数,不过没有格式化就先这么着吧

public String getSystemTime() {

Time t = new Time();

t.setToNow();

return t.toString();

}

public class MyBinder extends Binder {

MyService getService() {

return MyService.this;

}

}

}

4.  在Manifest里面声明服务,添加MyService声明.

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.gel.service"

    android:versionCode="1"

    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name" >

        <activity

            android:label="@string/app_name"

            android:name=".MainActivity" >

            <intent-filter >

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

       

 <service android:name=".MyService" android:exported="true"></service> 

    </application>

</manifest>

5. MainActivity代码实现

public class MainActivity extends Activity implements OnClickListener {

private MyService mMyService;

private TextView mTextView;

private Button bindServiceButton;

private Button unbindServiceButton;

private Context mContext;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

setupViews();

}

private ServiceConnection mServiceConnection = new ServiceConnection() {

// 当我bindService时,让TextView显示MyService里getSystemTime()方法的返回值

public void onServiceConnected(ComponentName name, IBinder service) {

// TODO Auto-generated method stub

mMyService = ((MyService.MyBinder) service).getService();

mTextView.setText("来自MyService的系统时间:"

+ mMyService.getSystemTime());

}

public void onServiceDisconnected(ComponentName name) {

// TODO Auto-generated method stub

}

};

public void setupViews() {

mContext = MainActivity.this;

mTextView = (TextView)findViewById(R.id.tvInfo);

bindServiceButton = (Button) findViewById(R.id.btnStart);

unbindServiceButton = (Button) findViewById(R.id.btnStop);

bindServiceButton.setOnClickListener(this);

unbindServiceButton.setOnClickListener(this);

}

public void onClick(View v) {

// TODO Auto-generated method stub

if (v == bindServiceButton) {

Intent i = new Intent();

i.setClass(MainActivity.this, MyService.class);

mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);

} else {

mContext.unbindService(mServiceConnection);

}

}

}

6. 运行结果.

日志输出:

下面这张流程图很好的诠释了"startService()"和"bindService()"两个方法调用的生命周期.

源码地址:

参考: