[Android学习笔记4]四大应用组件之一:Service 上
一、什么是Service
一个Service就是一个能够在后台执行长时操作的应用程序组件,并且不提供用户界面。一个应用程序组件能够启动一个Service,即使用户切换到另一个应用程序,这个Service也会继续在后台运行。另外,一个组件能够绑定一个跟它交互的Service,甚至是进程间通信(IPC)。例如,一个Service可以处理网络事务、播放音乐、执行文件I/O、或者跟CotentProvider交互,所有这些都是在后台完成的。
二、Service的形式
一个Service基本上有两种形式:
1. 被启动(Started):
当应用程序组件(如一个Activity)通过调用startService()方法启动的Service是“被启动(started)”的。Service一旦启动,它就能够无限期的在后台运行,即使启动它的组件被销毁。通常,一个被启动的Service执行一个单一操作,并且不给调用者返回结果。例如,这个Service可能在网络上下载或上传文件。当操作完成的时候,Service应该自己终止。
2. 被绑定(Bound):
当一个应用程序组件通过调用bindService()方法绑定的Service是“被绑定(bound)”的。一个被绑定的Service会提供一个允许组件跟Service交互的客户端接口,用于发送请求、获取结果、甚至是跨进程的进程间通信(IPC)。一个被绑定的Service的运行时间跟绑定它的应用程序组件一样长。多个组件能够绑定一个Service,但是只有所有这些绑定解绑,这个Service才被销毁。
Service能够被启动,也能够被绑定,看程序是否实现了运行组件启动的onStartCommand()方法或者允许绑定的onBind()方法。
三、Service的生命周期
1.以被启动方式产生的Sevice独立于启动该Service的组件的生命周期而存在,直到组件调用stopService()方法或直到其自己调用stopSelf()来终止自己。
2. 如果一个组件调用bindService()方法来创建这个Service(并且不调用onStartCommand()方法),那么这个Service只跟绑定的组件运行同样长的时间。一旦这个从所有的客户端解绑,系统就会销毁它。
四、StartService方式实例
StartService有两种方式:1.继承Service类;2.继承IntentService类;
先看第一种方式,继承Service类。
在清单文件中加入<Service></>标签:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.luoye.servicelearn.MainActivity"
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=".ServiceShow"></service> </application>
布局文件,声明两个Button,一个用于启动Service,一个用于停止Service
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
> <Button
android:id="@+id/start_service1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartService1"
android:onClick="buttonOnClickListener"
/> <Button
android:id="@+id/stop_service1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopService1"
android:onClick="buttonOnClickListener"
/> </LinearLayout>
MainActivity.java
package com.luoye.servicelearn; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} public void buttonOnClickListener(View v)
{
switch(v.getId())
{
case R.id.start_service1:
Intent intent_start = new Intent(this, ServiceShow.class);
startService(intent_start); //启动Service
break;
case R.id.stop_service1:
Intent intent_stop = new Intent(this, ServiceShow.class);
stopService(intent_stop); //停止Service
break;
} } }
ServiceShow.java
package com.luoye.servicelearn; import android.app.Service;
import android.content.Intent;
import android.os.IBinder; public class ServiceShow extends Service{ @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
} @Override
public void onCreate() { // Service创建时调用,在onStartCommand()之前调用,若Service存在,则不调用
// TODO Auto-generated method stub
super.onCreate();
System.out.println("Service Create");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) { //每次StartService都会调用
// TODO Auto-generated method stub
System.out.println("Service Start Command");
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() { //stopService()方法调用时,会调用该销毁函数
// TODO Auto-generated method stub
System.out.println("Service Stop");
super.onDestroy();
}
}
效果:
1 点击Start按钮后,查看LogCat信息:
调用了OnCreate()方法和onStartCommand()方法
2 再次点击Start按钮后,查看LogCat信息:
并没有重复调用OnCreate方法,而是调用了onStartCommand方法
3 点击Stop按钮后,查看Logcat信息:
调用了Destroy方法
4 再次点击Start按钮后,查看LogCat信息:
调用了OnCreate()方法和onStartCommand()方法,说明先前的Service已被销毁,此次Service为重新创建。
调用网上达人的一幅图作个总结:
第二种方式:继承IntentService类
IntentService执行以下操作:
IntentService类执行以下操作:
1. 创建一个独立与应用程序主线程的默认工作线程,执行所有的给onStartCommand()方法Intent的处理;
2. 创建一个工作队列,以便每次只给你的onHandleIntent()方法实现传递一个Intent,因此你不必担心多线程的问题;
3. 所有的启动请求都被处理之后终止这个服务,因此你不需要自己去调用stopSelf()方法;
4. 提供返回null的onBind()方法的默认实现;
5. 提供一个给工作队列发送Intent对象的onStartCommand()方法的默认实现和onHandleIntent()方法的实现。
所以这些加起来实际上只需要实现onHandleIntent()方法,来完成由客户提供的工作。当然别忘了构造函数,其中需调用父类构造函数。
实例这里不再赘述,也用一个图作个总结:
[Android学习笔记4]四大应用组件之一:Service 上的更多相关文章
- [Android学习笔记5]四大应用组件之一:Service 下
绑定方式的Service使用 在实现绑定服务时,最重要的是定义onBind()回调方法返回的接口,有三种方式: 1. 继承Binder类 2. 使用Messenger 3. 使用AIDL 这里对1,2 ...
- Android学习笔记(五一):服务Service(上)- IntentService
转自 http://blog.csdn.net/flowingflying/article/details/7616333 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的ac ...
- Android学习笔记:使用ViewPager组件实现图片切换
在很多App中,尤其是第一次安装启动后,都会出现几个图片进行一些app的介绍和说明,图片可以随着滑动而切换. 我们这里利用 ViewPager组件来演示如何实现这一点. 1.创建一个app工程,默认创 ...
- Android学习笔记 ImageSwitcher图片切换组件的使用
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- Android学习笔记 Toast屏幕提示组件的使用方法
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- Android学习笔记(24):进度条组件ProgressBar及其子类
ProgressBar作为进度条组件使用,它还派生了SeekBar(拖动条)和RatingBar(星级评分条). ProgressBar支持的XML属性: Attribute Name Related ...
- Android学习笔记 TextSwitcher文本切换组件的使用
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- 【转】 Pro Android学习笔记(七六):服务(1):local和remote
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
随机推荐
- Spark Standalone模式应用程序开发
作者:过往记忆 | 新浪微博:左手牵右手TEL | 能够转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明博客地址:http://www.iteblog.com/文章标题:<Spar ...
- mysql更改数据文件夹步骤与错误(ERROR 2002 (HY000))处理方法
1,关闭mysql服务: service mysqld stop 2,创建新建的文件夹 mkdir -p data 3,把曾经的文件夹转移到新的数据文件夹 mv /var/lib/mysql/ /da ...
- 安德鲁斯Selector简介
<? xml version="1.0" encoding="utf-8"? > <selector xmlns:android=" ...
- JS获取标签方法及兼容处理
document.getElementById('Id名'); // 所有浏览器 document.getElementsByTagName('标签名'); // 所有浏览器 document.ge ...
- 快速构建Windows 8风格应用28-临时应用数据
原文:快速构建Windows 8风格应用28-临时应用数据 本篇博文主要介绍临时应用数据概览.如何构建临时应用数据. 一.临时应用数据概览 临时应用数据相当于网页中缓存,这些数据文件是不能够漫游的,并 ...
- leetcode第27题--Implement strStr()
Implement strStr(). Returns a pointer to the first occurrence of needle in haystack, or null if need ...
- MyEclipse的真正价值——时间等于金钱
全世界成千上万的Java开发者选择MyEclipse作为首选的Eclipse IDE,甚至超过了著名的开发工具 IBM Rational和Eclipse Java. 为什么? 很简单,MyEclips ...
- C#中文本模板(.tt)
关于C#中文本模板(.tt)的简单应用 这两天做项目突遇 .tt文件,之前没有接触过,so查询学习做笔记,帮助记忆和后来者. 在项目添加中点击选择文本模板 下面贴出代码,做了简单的注释 1 2 3 4 ...
- leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal
代码实现:给定一个中序遍历和后序遍历怎么构造出这颗树!(假定树中没有重复的数字) 因为没有规定是左小右大的树,所以我们随意画一颗数,来进行判断应该是满足题意的. 3 / \ 2 4 /\ / \1 6 ...
- .NET Framework和C#版本历史概览
发布日期 .Net版本 C#版本 CLR版本 开发工具 功能介绍 2002 1.0 1.0 初始版本 Visual Studio .Net 初始版本 .NET框架结构,详见: 2003 1.1 ...