Service概念及用途:

Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以用Service在后台定时更新,而不用每打开应用的时候在去获取。

Service生命周期 :

Android Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。

Service与Activity通信:

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

1、添加一个类,在MainActivity所在包之下,继承自Service

2、在程序界面文件中添加控件

3、修改MainActivity中的方法,以及让MainActivity类实现OnClickListener接口

public class MainActivity extends Activity implements OnClickListener {
private LService mLService;
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显示LService里getSystemTime()方法的返回值
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mLService = ((LService.LBinder) service).getService();
mTextView.setText("I am from Service :" + mLService.getSystemTime());
}
public void onServiceDisconnected(ComponentName name) {
}
};
public void setupViews() {
mContext = MainActivity.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);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupViews();
}
}

4、注册Service

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

startService:onCreate()->onStart()此时调用程序设置里面可以看到Running Service有一个LService

stopService:onDestory()

bindService:onCreate()->onBind();此时Service已经被关闭

unbindService:onunBind->onDestory()

startService->bindService->unbindService:onCreate()->onStart()->onBind()->onunBind->onDestory();

当采用Context.startService()方法启动服务,与之有关的生命周期方法:onCreate()->onStart()->onDestory()

1>onCreate()方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或者bindService()方法,服务也只被创建一次;
onStart()方法只有采用Context.startService()方法启动服务时才会被调用,该方法在服务开始运行时被调用,多次调用startService()方法尽管不会多次创建服务,但onStart()方法会被多次调用。

2>onDestory()方法在服务被终止时被调用;
当采用Context.bindService方法启动服务,与之有关的生命周期方法:onCreate()->onBind()->onUnbind()->onDestory()

3>onBind()只有采用Context.bindService()方法启动服务时才会被调用,该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。

4>onUnbind()只有采用Context.unbindService()方法启动服务时才会回调该方法,该方法在调用者与服务解绑定时被调用;

5>如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法为:onCreate()->onStart()->onBind()->onUnBind()[重载后的方法需返回true]->onRebind();

6>服务不能自己运行,需要通过调用Context.startService()或者Context.bindService()方法启动服务。这两个方法都可能启动服务,但是它们使用场合不同,使用startService()方法启动服务,访问者与服务没有关连,即使访问者退出了,服务仍然运行,使用bindService()方法启动服务,访问者与服务绑定在一起,访问者一旦,服务也就终止,使用Context.startService()启动服务,只能调用 Context.stopService()结束服务,服务结束时会调用onDestory()方法;

通过startService()和stopService()启动关闭服务,适用于服务和访问者之间没有交互的情况。如果服务和访问者之间需要方法调用或者传递参数,则需要使用bindService()和unbindService()方法启动关闭服务;

采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法,此时访问者与服务绑定,如果要进行通信,onBind()方法需要返回一个Ibinder对象。如果访问者退出,系统先调用onUnbind()方法,再调用onDestory()方法。访问者与服务解除绑定可以通过unbindService()方法解绑。onUnbind()->onDestory()!

一个监听电话的实例

public class PhoneService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
private MediaRecorder recorder;
private File file = null;
@Override
public void onCreate() {
TelephonyManager manger = (TelephonyManager)
          getSystemService(Context.TELEPHONY_SERVICE);//内置的服务,通过getSystemService获取
manger.listen(new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:// 来电
break;
case TelephonyManager.CALL_STATE_OFFHOOK:// 接通电话
file = new File(Environment.getExternalStorageDirectory(),
incomingNumber + System.currentTimeMillis());
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 声音来源
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// 保存的声音类型
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 编码方式
try {
recorder.prepare();// 准备
recorder.start();// 开始录音
} catch (IOException e) {
}
break;
case TelephonyManager.CALL_STATE_IDLE:// 挂断电话后回归到空闲状态
if (recorder != null) {
recorder.stop();// 停止
recorder.release();// 释放
recorder = null;
uploadfile();
}
break;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
}
protected void uploadfile() {
new Thread(new Runnable() {
@Override
public void run() {
if (file != null && file.exists()) {
file.delete();
file = null;
}
}
}).start();
}
}

获取正在运行的Service

public class ServiceList extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
ActivityManager activityManger = (ActivityManager) getSystemService(ACTIVITY_SERVICE);// 获取Activity管理器
List<ActivityManager.RunningServiceInfo> serviceList = activityManger.getRunningServices(30);// 从窗口管理器中获取正在运行的Service
}
private boolean ServiceIsStart(List<ActivityManager.RunningServiceInfo> list, String className) {// 判断某个服务是否启动
for (int i = 0; i < list.size(); i++) {
if (className.equals(list.get(i).service.getClassName()))
return true;
}
return false;
}
private String getServicesName(List<ActivityManager.RunningServiceInfo> list) {// 获取所有服务的名称
String res = "";
for (int i = 0; i < list.size(); i++) {
res += list.get(i).service.getClassName() + "/n";
}
return res;
}
}

Android Service 生命周期的更多相关文章

  1. Android Service生命周期及用法

    Service概念及用途:Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行, ...

  2. Android Service 生命周期和使用注意项

    一.基础知识 服务一般分为两种: 1:本地服务, Local Service 用于应用程序内部.在Service可以调用Context.startService()启动,调用Context.stopS ...

  3. 对于Android Service 生命周期进行全解析

    应用程序组件有一个生命周期——一开始Android实例化他们响应意图,直到结束实例被销毁.在这期间,他们有时候处于激活状态,有时候处于非激 活状态:对于活动,对用户有时候可见,有时候不可见.组件生命周 ...

  4. Android Service生命周期 Service里面的onStartCommand()方法详解

    在Demo上,Start一个Service之后,执行顺序:onCreate - > onStartCommand 然后关闭应用,会重新执行上面两步. 但是把代码拷贝到游戏工程发现,关闭游戏后,只 ...

  5. Service 生命周期

    有了 Service 类我们如何启动他呢,有两种方法: • Context.startService() • Context.bindService()  1.  在同一个应用任何地方调用 start ...

  6. Android生命周期和Service生命周期

    android生命周期 运行:oncreate → onstart → onresume暂停:onresume → onpause:再次运行:onresume停止:onpause → onstop → ...

  7. Android(java)学习笔记171:Service生命周期

    1.Service的生命周期         Android中的Service(服务)与Activity不同,它是不能和用户交互,不能自己启动的,运行在后台的程序,如果我们退出应用的时候,Servic ...

  8. Android中startService的使用及Service生命周期

    Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法.本文仅仅探讨纯startService的使用.不 ...

  9. Android(java)学习笔记114:Service生命周期

    1.Service的生命周期         Android中的Service(服务)与Activity不同,它是不能和用户交互,不能自己启动的,运行在后台的程序,如果我们退出应用的时候,Servic ...

随机推荐

  1. CakePHP模型中使用join的多种写法

    Cake写法 App::import("Model","Client"); $this->Client = & new Client(); $th ...

  2. zedboard学习第一篇

    1. 刚开始学习使用,不知道从哪里开始,手上的资料也很乱,至于这个板子需要学什么也不清楚. 2. 第一个工程就从helloworld开始吧,Zed板上的Zynq是一个PS(processing sys ...

  3. 读google c++规范笔记

    全局变量在main函数之前初始化原则上禁止拷贝构造函数和赋值函数如果只有数据,没有方法,可以用struct析构函数声明为虚函数尽量避免重载操作符 难以定位的bug 误以为简单的操作存取控制 可以放到声 ...

  4. 「日常训练」Uncle Tom's Inherited Land*(HDU-1507)

    题意与分析 题意是这样的:给你一个\(N\times M\)的图,其中有一些点不能放置\(1\times 2\)大小的矩形,矩形可以横着放可以竖着放,问剩下的格子中,最多能够放多少个矩形. 注意到是\ ...

  5. 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)

    题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...

  6. Selenium 入门到精通系列:四

    Selenium 入门到精通系列 PS:鼠标右键.鼠标悬停.键盘操作方法 例子 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2019 ...

  7. python3-声音处理

    先来说下二进制读写文件,这需要struct库 #二进制文件读写 import struct a= b=- # print(struct.pack("h",b)) # print(s ...

  8. 【halcon】算子

    算子 rgb1_to_gray  灰度化 threshold:英文是阈的意思    二值化算子 Connection Compute connected components of a region. ...

  9. 【C#】arcface人脸识别使用问题分析

    arcface上线了新版 正好有空 赶紧下载体验了一番 凡是过程中也遇到一些问题 1.初始化 [DllImport("libarcsoft_face_engine.dll", En ...

  10. 火狐metamask账号

    火狐metamask lock trophy pyramid sunny aim inmate body sense sing castle cinnamon cram