Android服务Service
安卓Service服务
一 Service简介
Service是运行在后台的,没有界面的,用来处理耗时比较长的。Service不是一个单独的进程,也不是一个单独的线程。
Service有两种类型:
本地服务(Local Service):用于应用程序内部
远程服务(Remote Sercie):用于android系统内部的应用程序之间
前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
二 Service的生命周期以及启动方式
Service有startService()和bindService()两种启动Service方法,每种方法Service的生命周期是不一样的。
1 通过startService()启动服务
Service会经历 onCreate() --> onStartCommand()
stopService()的时候直接onDestroy()
如果是调用者直接退出而没有调用stopService的话,Service会一直在后台运行, 下次调用者再起来仍然可以stopService()。
2 通过bindService() 启动服务
Service会运行onCreate()-->onBind() ,此时调用者和Service绑定在一起
unbindService()的时候 运行 onUnbind()-->onDestroyed()
调用者退出了,Srevice就会调用onUnbind()-->onDestroyed()
所谓绑定在一起就共存亡了。
注意:Service的onCreate()的方法只会被调用一次,也就是说无论你多少次的调用startService()或bindService(),Service只被创建一次。
Android中的服务和Windows中的服务是类似的,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关联,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。
如果采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
如果采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定,也就是说onCreate()和onBind()方法并不会被多次调用。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的 onUnbind()-->onDestroy()方法。
三 具体运用
1、开始服务,开始服务一般都是界面和服务简单数据交互。示例为从主界面传递一个值给服务,服务接收。
流程:
示例:
项目工程目录结构:
package com.example.service;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity
{
Button button1;
@Override
protected void onCreate ( Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) this.findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener()
{
@Override
public void onClick ( View v)
{
startMyService();
}
});
}
// 服务开启方法
protected void startMyService ()
{
Intent intent = new Intent("com.example.service.MyService");
// 利用Intent向服务传递数据,数据通过界面输入
intent.putExtra("myMessage", "MainActivity--lhyService123456【这是活动前台传递过来的数据】!");
this.startService(intent);//开始服务
}
@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;
}
}
package com.example.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service
{
@Override
public IBinder onBind ( Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate ()
{
Log.i("lhy", "服务创建onCreate ()-----------");
super.onCreate();
}
// 启动服务,目前该方法不用
// @Override
// public void onStart ( Intent intent, int startId)
// {
// // TODO Auto-generated method stub
// super.onStart(intent, startId);
// }
@Override
public int onStartCommand ( Intent intent, int flags, int startId)
{
Log.i("lhy", "服务开启,在后台运行,正在做事情当中。。。。。。。。。。。。。");
// 接收activity传递过来的数据
String message = intent.getStringExtra("myMessage");
Log.i("lhy", "MyService--服务后台接收前台活动输入的数据:" + message);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy ()
{
// TODO Auto-generated method stub
super.onDestroy();
}
}
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="开始服务示例演示" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="38dp"
android:text="开始服务" />
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="38dp"
android:ems="10" >
<requestFocus />
</EditText>
</RelativeLayout>
<service android:name="com.example.service.MyService" >
<intent-filter>
<action android:name="com.example.service.MyService" />
</intent-filter>
</service>
控制台输出信息:MainActivity--lhyService123456 是活动界面传递过来,在服务端接收的数据
2、绑定服务,一般都是界面与服务深层次数据交互,进程之间数据传递,绑定服务需要连接对象,连接对象中可以获得服务类的内部类对象,这样活动前台可以利用服务类内部类对象操作服务里面的任何方法和属性。
具体流程:
示例:
项目工程目录结构:
package com.example.servicebind;
import com.example.servicebind.MyServices.MyBind;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity
{
Button button1;
Button button2;
MyBind myBind;
@Override
protected void onCreate ( Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) this.findViewById(R.id.button1);
button1.setOnClickListener(onClickListener);
button2 = (Button) this.findViewById(R.id.button2);
button2.setOnClickListener(onClickListener);
}
// 按钮事件监听
OnClickListener onClickListener = new OnClickListener()
{
@Override
public void onClick ( View v)
{
switch (v.getId())
{
case R.id.button1:
startMyServiceBind();
break;
case R.id.button2:
stopMyServiceBind();
break;
default:
break;
}
}
};
// 按钮点击事件监听方法,也就是绑定服务
protected void startMyServiceBind ()
{
// 如果部内部类对象不为空,那么就直接调用内部类方法,否则重新绑定服务,建立连接
if (myBind != null)
{
// 利用服务内部对象,调用服务内部类方法,相当于调用了服务类的的数据
myBind.myBindFun();
Log.i("lhy", myBind.getStr());
}
else
{
// 绑定服务方法*******************************
Intent intent = new Intent("com.example.servicebind.MyServices");
// intent意图,serviceConnection连接, Context.BIND_AUTO_CREATE绑定自动创建
this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
}
protected void stopMyServiceBind ()
{
if (serviceConnection == null)
{
return;
}
else
{
this.unbindService(serviceConnection);
Log.i("lhy", "服务解除!!");
serviceConnection = null;
}
}
// 绑定服务开始,类似于事件监听,一个服务连接
ServiceConnection serviceConnection = new ServiceConnection()
{
// 绑定失败之后
@Override
public void onServiceDisconnected ( ComponentName name)
{
// TODO Auto-generated method stub
}
// 绑定成功之后,也就是服务建立了连接
@Override
public void onServiceConnected ( ComponentName name, IBinder service)
{
// 获取服务类内部对象,IBinder service,该参数就是服务类回调方法OnBind()返回的数据,也就是服务内部对象
myBind = (MyBind) service;
}
};
}
package com.example.servicebind;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyServices extends Service
{
// 服务类成员变量
String str = "MyServiceMessage";
// 服务类成员方法
public void fun1 ()
{
Log.i("lhy", "服务内部方法fun1()");
}
// 服务类内部类
public class MyBind extends Binder
{
// 内部类调用外部类方法
public void myBindFun ()
{
fun1();
}
// 内部类调用外部类成员变量
public void setStr ( String str)
{
MyServices.this.str = str;
}
public String getStr ()
{
return MyServices.this.str;
}
}
@Override
public void onCreate ()
{
Log.i("lhy", "服务创建onCreate()");
super.onCreate();
}
@Override
public IBinder onBind ( Intent intent)
{
Log.i("lhy", "服务绑定onBind()");
// 实例化内部类对象,该对象可以无条件调用其外部类(本服务类)的一切方法和成员变量
return new MyBind();
}
@Override
public boolean onUnbind ( Intent intent)
{
Log.i("lhy", "服务解除onUnbind()");
return super.onUnbind(intent);
}
}
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绑定服务演示" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginTop="23dp"
android:text="绑定服务" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="14dp"
android:text="解除服务" />
</RelativeLayout>
最后在AndroidMainfest.xml文件中注册服务:
<intent-filter>
<action android:name="com.example.servicebind.MyServices" />
</intent-filter>
</service>
Android服务Service的更多相关文章
- Android服务Service具体解释(作用,生命周期,AIDL)系列文章-为什么须要服务呢?
Android服务Service具体解释(作用,生命周期,AIDL) 近期沉迷于上班,没有时间写博客了.解衣入睡,未眠.随起床写一篇博客压压惊! ##我们android系统为什么须要服务Service ...
- Android服务(Service)研究
Service是android四大组件之一,没有用户界面,一直在后台运行. 为什么使用Service启动新线程执行耗时任务,而不直接在Activity中启动一个子线程处理? 1.Activity会被用 ...
- Android服务Service总结
转自 http://blog.csdn.net/liuhe688/article/details/6874378 富貴必從勤苦得,男兒須讀五車書.唐.杜甫<柏學士茅屋> 作为程序员的我们, ...
- android服务Service(上)- IntentService
Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...
- Android服务——Service
服务 Service 是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到服务,以与之进行 ...
- android 服务service开启和关闭
startService()方法开启一个服务. 服务只会开启一次,如果服务已经创建,并且没有销毁,多次调用startService方法只会执行onStartCommand方法和onStart方法. 服 ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
- Android服务之Service(其一)
android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...
- Android 服务类Service 的详细学习
http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有 ...
随机推荐
- 用vue做一个酷炫的menu
写在前面 最近看到一个非常酷炫的menu插件,一直想把它鼓捣成vue形式,谁让我是vue的死灰粉呢,如果这都不算爱
- Mybatis的Service循环调用错误
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'z ...
- 原生js的容易忽略的相似点(二)
1.new Object 和字面量 {}测试; <script type="text/javascript"> //1.new出来对象 console.log(obj, ...
- Two-Phase Commit (2PC)
两阶段提交模式像极了比赛发令:“预备,开始!”
- 迅为iMX6UL Cortex-A7架构单核ARM开发板接口介绍-支持定制
支持商业级和工业级核心板 1. POWER 电源接口电源输入为 5V/2A+,给核心板提供 5V 电源,给底板供电.原理图部分如下图所示. 电源接口位置如下图所示. 2. SWITCH 电源开关轻触电 ...
- Unity Shader-热空气扭曲效果
GrabPass GrabPass是Unity为我们提供的一个很方便的功能,可以直接将当前屏幕内容渲染到一张贴图上,我们可以直接在shader中使用这张贴图而不用自己去实现渲染到贴图这样的一个过程,大 ...
- JS concat() 方法
[数组元素的合并] 一. concat() 方法 concat() 方法用于连接两个或多个数组. 返回一个新的数组.该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的.如果 ...
- log4j.xml 精选的log4j.xml文档,比较详细,网上的版本很多,这个版本相对而言比较完整
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE log4j:configuration PUB ...
- Java Thread.join()详解
一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法 一.使用方式. join是Thread类的 ...
- 牛客OI赛制测试赛2 D 星光晚餐
链接:https://www.nowcoder.com/acm/contest/185/D来源:牛客网 题目描述 Johnson和Nancy要在星光下吃晚餐.这是一件很浪漫的事情. 为了增加星光晚餐那 ...