1.service简介:service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。Service是在一段不定的时间运行在后台,不和用户交互应用组件。每个Service必须在manifest中 通过<service>来声明。可以通过context.startservice和context.bindserverice来启动。

2.Service的启动的两种方式:

  a.使用context.startService() 启动Service(本地服务 Local Service 用于应用程序内部)

目的:用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。

特点:使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。

其生命周期为context.startService() ->onCreate()- >onStart(可多次调用)->Service running-->context.stopService()  ->onDestroy() ->Service stop 
在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy

b.对于bindService()启动Service()

目的:用于远程服务 Remote Service 用于android系统内部的应用程序之间。比如天气预报服务。

特点:调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
其生命周期为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。
3.拥有service进程的优先级往往高一些

官方文档告诉我们,Android系统会尽量保持拥有service的进程运行,只要在该service已经被启动(start)或者客户端连接(bindService)到它。当内存不足时,需要保持,拥有service的进程具有较高的优先级。

  • 如果service正在调用onCreate,onStartCommand或者onDestory方法,那么用于当前service的进程则变为前台进程以避免被killed。
  • 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
  • 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
  • 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。

4.service是一个线程还是一个进程:

答案都不是,因为service是长期的,而进程是短期的。service是在主进程中被开启的。当主进程退出,而service还在服务。进程就好比一个送快递的小哥,而service就好比你收到的那个快递。小哥人走了,你还是可以看这本书很久的啊。

5.Service与Activity通信:

Service后端的数据最终还是要呈现在前端Activity之上的,因为启动Service时,系统会重新开启一个新的进程,这就涉及到不同进程间通信的问题了(AIDL)这一节我不作过多描述,当我们想获取启动的Service实例时,我们可以用到bindService和onBindService方法,它们分别执行了Service中IBinder()和onUnbind()方法。

为了让大家 更容易理解,我写了一个简单的Demo,大家可以模仿着我,一步一步的来。

第一步:新建一个Android工程,我这里命名为ServiceDemo.

第二步:修改main.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:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/startservice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="startService"
/>
<Button
android:id="@+id/stopservice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="stopService"
/>
<Button
android:id="@+id/bindservice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="bindService"
/>
<Button
android:id="@+id/unbindservice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="unbindService"
/>
</LinearLayout>

第三步:新建一个Service,命名为MyService.java代码如下:

package com.tutor.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.text.format.Time;
import android.util.Log;
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;
}
}
}

第四步:修改ServiceDemo.java,代码如下:

package com.tutor.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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ServiceDemo extends Activity implements OnClickListener{ private MyService mMyService;
private TextView mTextView;
private Button startServiceButton;
private Button stopServiceButton;
private Button bindServiceButton;
private Button unbindServiceButton;
private Context mContext; //这里需要用到ServiceConnection在Context.bindService和context.unBindService()里用到
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("I am frome Service :" + mMyService.getSystemTime());
} public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub }
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupViews();
} public void setupViews(){ mContext = ServiceDemo.this;
mTextView = (TextView)findViewById(R.id.text); startServiceButton = (Button)findViewById(R.id.startservice);
stopServiceButton = (Button)findViewById(R.id.stopservice);
bindServiceButton = (Button)findViewById(R.id.bindservice);
unbindServiceButton = (Button)findViewById(R.id.unbindservice); startServiceButton.setOnClickListener(this);
stopServiceButton.setOnClickListener(this);
bindServiceButton.setOnClickListener(this);
unbindServiceButton.setOnClickListener(this);
} public void onClick(View v) {
// TODO Auto-generated method stub
if(v == startServiceButton){
Intent i = new Intent();
i.setClass(ServiceDemo.this, MyService.class);
mContext.startService(i);
}else if(v == stopServiceButton){
Intent i = new Intent();
i.setClass(ServiceDemo.this, MyService.class);
mContext.stopService(i);
}else if(v == bindServiceButton){
Intent i = new Intent();
i.setClass(ServiceDemo.this, MyService.class);
mContext.bindService(i, mServiceConnection, BIND_AUTO_CREATE);
}else{
mContext.unbindService(mServiceConnection);
}
} }

第五步:修改AndroidManifest.xml代码(将我们新建的MyService注册进去如下代码第14行:)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutor.servicedemo"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ServiceDemo"
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=".MyService" android:exported="true"></service>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>

最新文章

  1. Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
  2. UEditor百度编辑器,工具栏上自定义添加一个普通按钮
  3. iOS开发 - OC - 实现本地数据存储的几种方式一
  4. iOS 注意事项
  5. 转-Asp.Net MVC及Web API框架配置会碰到的几个问题及解决方案
  6. 使用htmlunit在线解析网页信息
  7. 【VB超简单入门】三、开始编程
  8. windows 端搭建nfs 服务器
  9. 程序员带你学习安卓开发-XML文档的创建与解析
  10. 关于IOS开发者账号一点总结
  11. Oracle GoldenGate学习之Goldengate介绍
  12. Linux下动态库使用
  13. Oracle 高级查询、事物、过程及函数
  14. 用一个jsp实现对数据库发访问
  15. React native开发中常见的错误
  16. JNI技术简介-android学习之旅(92)
  17. 一次Spring Bean初始化顺序问题排查记录
  18. layui
  19. axios 用法简介(转载)
  20. SSH免费登录

热门文章

  1. Android平台利用OpenCL框架实现并行开发初试
  2. Apache 配置参数
  3. BeatSaber节奏光剑双手柄MR教程
  4. 20145201 《Java程序设计》第三周学习总结
  5. JSONObject使用方法
  6. nodejs 设计模式
  7. SQL中比较好的For xml 用法实例
  8. Substring with Concatenation of All Words, 返回字符串中包含字符串数组所有字符串元素连接而成的字串的位置
  9. matplotlib之散点图
  10. LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD