6 四大组件之Service

6-1 Servie概述

组件篇——Service

定义:
  1.后台运行,不可见,没有界面
  2.优先级高于Activity

  Service是Android系统的后台服务组件,适用于开发无界面、长时间运行的应用功能。

Service特点如下:

  没有用户界面

  不会轻易被Android系统终止

  在系统资源恢复后Service也将自动恢复

  运行状态

  可用于进程间通信

用途:
  播放音乐,记录地理信息位置的改变,监听某种动作

注意:
  -运行在主线程,不能用它来做耗时的请求或者动作
  -可以在服务中开一个线程,在线程中做耗时操作

类型:

  本地服务(Local Service):

    应用程序内部

    start方式:startService stopService stopSelf stopSelfResult

      启动方式使用Service

      通过调用Context.startService()启动Service,通过调用Context.stopService()或Service.stopSefl()停止Service

    Bind方式:bindService unbindService

      绑定方式使用Service

      使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接

      如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service

  远程服务(Remote Service):

    Android系统内部的应用程序间之间

    定义IBinder接口

生命周期:

  通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService(),此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onStart(),如果服务已经启动再次调用只会触发onStart()方法

  onCreate():Service的生命周期开始,完成Service的初始化工作;

  onStart():活动生命周期开始;

  onDestroy():Service的生命周期结束,释放Service所有占用的资源;


  使用bindService()启动的服务与调用者绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onBind(),如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()-->onDestory(),想主动解除绑定可使用Contex.unbindService(),系统依次调用onUnbind()-->onDestory();

  bindService()绑定Servcie, onCreate()和onBindle()将先后被调用。

  unbindService()取消绑定Servcie,onUnbind()将被调用,如果onUnbind()返回true,则表示在调用者绑定新服务时,onRebind()函数将被调用

非绑定式的service的生命周期
  startService()--->onCreate()--->onStartCommand()--->ServingRunning--->onStop()--->onDestory()服务停止

绑定式的service的生命周期
  bindService()--->onCreate()--->onBind()--->用户与服务绑定 在解绑服务 onUnbind()--->onDestory()服务停止

start方式特点:

  -服务跟启动源没有任何联系 

  -无法得到服务对象

Bind方式特点:

  -通过Ibinder接口实例,返回一个ServerConnnection对象给启动源
  -通过ServiceConnection对象的相关方法可以得到Service对象

 

6-2 Start启动

start方式的启动时:

  第一次创建Service需要调用onCreate(),而后调用onStartCommand(),不管调用了多少次的onStartCOmmand(),停止的时候只调用一次onDestroy();

StartService
1. 使用方法:
  (1)写一个MyStartService继承自Service,重写它的各种方法onCreate()、onStartCommand()、onDestory()
  (2)在AndroidManifest.xml中注册这个Service
  (3)在主线程Activity中通过startSerice(intent)方式启动
  (4)通过stopService(intent)方式停止

2. 关于StartService
  (1)启动方式是通过启动intent方式实现
  (2)启动之后该Service和启动源没有关系,即使主线程退出了,service还会继续运行

由于Service和Activity类似,属于Android四大组件之一,所以我们需要在AndroidManifest.xml中进行注册。我们的组件都需要在AndroidManifest.xml中进行注册。

3.启动Service

显式启动

  Intent中指明Service所在的类,并调用startService(Intent)函数启动Service

final Intent serviceIntent = new Intent(this,RandomService.class);startService(serviceIntent);

隐式启动

  需要隐式开启Service,则可以在注册Service时,声明Intent-filter的action属性

<service android:name=".RandomService" ><intent-filter><action android:name="StartRandomService" /></intent-filter>
</service>
final Intent serviceIntent = new Intent();
serviceIntent.setAction("edu.hrbeu.RandomService");

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Start:" /><Buttonandroid:id="@+id/start"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="StartService" /><Buttonandroid:id="@+id/stop"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="StopService" /><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Bind:" /><Buttonandroid:id="@+id/bind"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="BindService" /><Buttonandroid:id="@+id/play"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="播放" /><Buttonandroid:id="@+id/pause"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="暂停" /><Buttonandroid:id="@+id/next"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="下一首" /><Buttonandroid:id="@+id/pervious"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="上一首" /><Buttonandroid:id="@+id/unbind"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="UnBindService" /></LinearLayout>

MainActivity.java

package com.example.test;import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;public class MainActivity extends Activity {Intent intent1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void doClick(View v) {switch (v.getId()) {case R.id.start:intent1 = new Intent(MainActivity.this, MyStartService.class);startService(intent1);break;case R.id.stop:stopService(intent1);break;}}
}

MyStartService.java

package com.example.test;import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;public class MyStartService extends Service {@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i("info", "Service--onCreate()");super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubLog.i("info", "Service--onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i("info", "Service--onDestroy()");super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i("info", "Service--onBind()");return null;}}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.test"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="15"android:targetSdkVersion="15" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".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="com.example.servicedemo.MyStartService"></service></application></manifest>

 

6-3 Bind启动

1.通过绑定服务获取回传数据:
  通过Ibinder接口实例(继承的类里面返回一个Ibinder对象的抽象方法),返回一个serviceConnection对象给启动源,因为Ibinder里面含有我们要的数据,这里可以定义个内部类继承Binder里面做想返回的参数

 

2.使用onBind()方法的IBinder返回值给启动源返回信息 但是IBinder不能直接使用 需要通过Ibinder接口实例 返回一个ServiceConnection对象给启动源,通过ServiceConnection对象的相关方法可以得到Service,MyBinder是继承自Binder类的,而Binder类实际上实现了IBinder接口。

public class MyBinder extends Binder{public MyBindServic getService(){return MyBindService.this;//返回这个Service的实例}
} public IBunder onBind(Intent intent){return new MyBinder();
}

 

3.在启动源定义ServiceConnection 该对象在绑定服务时传输到服务端(bindService(intent,conn,Service.BIND_AUTO_CREATE)) 绑定后 通过onServiceConnected() 方法获取service对象

 

4.unbindservice执行后,不能重复调用,会报错,并且在destroy的时候必须解绑, stopserveice则不会,

 

5.服务的两种启动方式:

  1).通过startService(Intent intent)启动,stopService(Intent intent)停止,比较简单。服务启动后与启动源无关,也无返回服务本身。需注意要在配置文件中注册服务。

  2).通过bindService(Intent intent,ServiceConnection conn,int flags)绑定服务启动,unbindService(ServiceConnection conn)去绑定停止,该方式可以返回服务本身,与启动源相关。

 

6.通过bindService绑定服务启动的具体步骤:

  1)Intent intent = new Intent(上下文, 目标服务名.class);
    bindService(intent, conn, Service.BIND_AUTO_CREATE);//绑定

  2)在自定义的服务类中通过自定义一个内部类:
    public class MyBinder extends Binder {
      public MyBindService getService() {
        return MyBindService.this;// 获取服务
      }
    }来返回服务本身
    同时在自定义服务类重新父类Service的方法:
    public IBinder onBind(Intent intent) {
      // TODO Auto-generated method stub
      return new MyBinder();
    }
    该方法可返回服务本身.

    3)在启动源的Activity中创建一个ServiceConnection实例,初始化ServiceConnection接口,在接口方法中重写方法

      ServiceConnection conn = new ServiceConnection() {
        //当启动源跟service的连接意外丢失的时候会调用
        //比如service崩溃了,或被强行杀死了
        public void onServiceDisconnected(ComponentName name) {
        }
        //当启动源跟service成功连接之后会调用这个方法

        public void onServiceConnected(ComponentName name, IBinder service) {
          myBindService = ((MyBinder)service).getService();//大类转化为自身的小类,获取内部类中的方法,从而获得服务本身
      }};

    4)bindService()中指定ServiceConnection conn参数

     bindService(intent2, conn, Service.BIND_AUTO_CREATE);

    5)在自定义的继承于Servic类的类中,添加需要的方法,在启动Service的Activity中可以直接调用服务中的方法。

  通过bindService()启动的服务是和启动源(Activity)绑定在一起的,如果Activity退出的时候没有调用unbindService()进行解绑定(停止),那么程序会报错。所以我们需要在Activity的onDestroy()方法中调用unbindService()进行解绑定。而且对于已经解绑定的服务再次进行解绑定,那么也会报错,这点和通过startService启动的服务不同,stopService()方法可以调用多次。

 

7.StartService和BindService

  1). StartService启动后启动源和Service没有关系,BindService调用bindService()启动service后启动源和Service相关,在退出activity之前必须要调用unbindService()取消绑定。

  2). startService()和bindService()可以混合使用。如果我们想要Activity退出了,但是服务还在继续,那么我们就要选用startService的方式来启动服务,如果我们想要在Activity中获取Service对象,那么我们需要用bindService方法结合ServiceConnection来启动Service,但是这种方法,由于将Service和Activity绑定在了一起,所以当Activity退出的时候,我们需要unbindService()来停掉Service,否则就会报错。

 

8.BindService

  通过bindService()得到的Service是和启动源(Activity)绑定在一起的,在Activity退出的时候需要调用unbindService()进行解绑定(停止)。

  调用bindService()时会调用到目标Service的onBind()函数,通过IBinder接口实例,返回一个ServiceConnection对象给启动源。然后启动源可以通过ServiceConnection对象得到启动的Service对象

MyBindService.java

package com.example.test;import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;public class MyBindService extends Service{@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i("info", "BindService--onCreate()");super.onCreate();}public class MyBinder extends Binder{public MyBindService getService(){return MyBindService.this;}}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i("info", "BindService--onBind()");return new MyBinder();}@Overridepublic void unbindService(ServiceConnection conn) {// TODO Auto-generated method stubLog.i("info", "BindService--unbindService()");super.unbindService(conn);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i("info", "BindService--onDestroy()");super.onDestroy();}public void Play(){Log.i("info", "播放");}public void Pause(){Log.i("info", "暂停");}public void Pervious(){Log.i("info", "上一首");}public void next(){Log.i("info", "下一首");}
}

MainActivity.java

package com.example.test;import com.example.test.MyBindService.MyBinder;import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.View;public class MainActivity extends Activity {Intent intent1;Intent intent2;MyBindService service;ServiceConnection conn = new ServiceConnection() {@Override//当服务跟启动源断开的时候 会自动回调public void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub
            }@Override//当服务跟启动源连接的时候 会自动回调public void onServiceConnected(ComponentName name, IBinder binder) {// TODO Auto-generated method stubservice = ((MyBinder)binder).getService();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void doClick(View v){switch (v.getId()) {case R.id.start:intent1 =     new Intent(MainActivity.this, MyStartService.class);startService(intent1);break;case R.id.stop:stopService(intent1);break;case R.id.play:service.Play();break;case R.id.pause:service.Pause();break;case R.id.pervious:service.Pervious();break;case R.id.next:service.next();break;case R.id.bind:
//绑定Service:
//bindService()方法绑定服务
//Intent对象传递给bindService(),声明需要启动的Service
//Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立Service;同时也告知Android系统,这个Service的重要程度与调用者相同
            intent2 = new Intent(MainActivity.this, MyBindService.class);startService(intent2);bindService(intent2, conn, Service.BIND_AUTO_CREATE);//绑定了break;case R.id.unbind:unbindService(conn);break;}}@Overrideprotected void onDestroy() {// TODO Auto-generated method stub
        stopService(intent2);
//解绑Service:
//取消绑定使用unbindService()方法,并将ServiceConnnection对象传递给unbindService()方法。
//unbindService()方法调用成功后,系统并不会再次调用onServiceDisconnected()方法
//onServiceDisconnected()方法仅在意外断开绑定时才被调用。
        unbindService(conn);//解绑定super.onDestroy();}@Overridepublic 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;}}

 

转载于:https://www.cnblogs.com/crazyzx/articles/5350862.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WCF服务寄宿IIS时.SVC文件无法浏览的解决办法

在IIS中托管服务和经典的ASMX Web服务托管相似,需要在IIS下创建虚拟目录,并提供一个.svc文件和Web.config配置文件。另外,托管时,服务的基地址必须与.svc文件的地址相同。 一、操作步骤: (1)打开IIS,新建网站,选择物理路径 (2)打开IIS,在默认网站下添加应用程序,…

python自动生成鸡汤文_用20行Python代码生成鸡汤,打造AI咪蒙指日可待。

作者&#xff1a;Ramtin Alami“Don’t think of the overwhelming majority of the impossible.” “不要去想不可能之事” “Grew up your bliss and the world.” “努力赢得自己的幸福和世界” “what we would end create, creates the ground and you are the one to war…

他毕业两年,博客一年,时间

这是2014年10个月。时光匆匆&#xff0c;看到该公司的新鲜新的一年。有时&#xff0c;一个想法。其实&#xff0c;我在这个城市工作了两年多&#xff0c;总是觉得自己老了。从一般再聘请两名现在厂家机构和学校&#xff0c;懵懵懂懂从校园到完成社区&#xff0c;来写个总结&…

linux shell之替换目录下包含关键字所有文本里面的内容

1 问题 替换目录下包含关键字所有文本里面的内容 比如在目录 /root/chenyu/cy/下&#xff0c;把包含文本/A/B C替换成文本EF 2 解决办法 命令如下 grep -Rl /A/B\ C /root/chenyu/c* | xargs sed -i s#/A/B\ C#EF#g 我们也可以这样 grep -Rl /A/B\ C /root/chenyu/c/ | x…

C#语法糖系列 —— 第一篇:聊聊 params 参数底层玩法

首先说说为什么要写这个系列&#xff0c;大概有两点原因。这种文章阅读量确实高...对 IL 和 汇编代码 的学习巩固所以就决定写一下这个系列&#xff0c;如果大家能从中有所收获&#xff0c;那就更好啦&#xff01;一&#xff1a;params 应用层玩法 首先上一段 测试代码。class …

nginx 修改配置文件使之支持pathinfo,且隐藏index.php

声明环境&#xff1a; nginx centos6.8 使用lnmp一键包搭建环境&#xff08;2019年2月19日 &#xff09;以前使用过别的办法去修改配置文件&#xff0c;但是过于繁琐&#xff0c;最近发现新版本中&#xff0c;在nginx 的 conf目录下发现了文件“enable-php-pathinfo.conf”&am…

Android开发经典笔试面试题汇总(持续更新中)

1.我们都知道Handler是线程与Activity通信的桥梁&#xff0c;假设线程处理不当。你的机器就会变得非常慢&#xff0c;那么线程销毁的方法是&#xff1a;&#xff08;A&#xff09;A. onDestroy()B. onClear()C. onFinish()D. onStop()理解&#xff1a;正确销毁线程的方法应该是…

WCF服务自托管(Self-Hosting)

WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有:IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。 当客户端和服务端之间的进程有明确的边界时,使用自托管,需要注意的…

学习进度04

第五周所花时间&#xff08;分钟&#xff09;100代码量&#xff08;行&#xff09;50博客量&#xff08;篇&#xff09;2了解到的知识点作为合作的团队要制定统一的标准转载于:https://www.cnblogs.com/liguoshuai/p/5352590.html

android 微信分享gif图,android后台动态创建图片并实现微信分享

今天就记录一下。先说明一下&#xff0c;之前没有做过类似的东西&#xff0c;百度了一两天才知道&#xff0c;说来很惭愧、有点笨&#xff0c;只能这样说。在我的脑里只明白&#xff0c;如果要动态创建图片&#xff1a;一、就是new 嘛二、就是LayoutInflater.from()这种。而微信…

python字符串前面去两位_在Python 3中删除字符串文字前面的'b'字符do

I am new in python programming and i am a bit confused. I try to get the bytes from a string to hash and encrypt but i gotb...b character in front of string just like the below example. Is any way avoid this?.Can anyone give a solution? Sorry for this si…

C语言之去掉https链接的默认443端口

1 问题 去掉https链接的默认443端口 2 代码实现 #include <stdio.h> #include <string.h> #include <stdlib.h>#define BOOL int #define TRUE 1 #define FALSE 0/**判断字符串str1是不是str2开头*/ int is_begin_with(const char *str1, char *str2) {if(…

仅需一个参数就可搞定OneProxy的VIP机制

文章转自&#xff1a;http://card.weibo.com/article/h5/s#cid1001603863326047255626&vid&extparam&from&wm0&ip182.50.119.226现在都讲求无单点的架构&#xff0c;OneProxy也不例外&#xff0c;虽然已经有进程级别的自动重起机制&#xff08;--keepalive…

关于在Windows下AndroidStudio.使用React-Native开发android报错红屏“run react-native start”解决

以下是报错&#xff0c;不过他已经给了解决办法&#xff0c;报错提示的大概中文译为“无法加载脚本&#xff0c;请确保你的Metro服务以及那个包正确”&#xff0c;由于我个人并不是专业安卓&#xff0c;公司项目没办法就上了&#xff0c;所以我就不关包了&#xff0c;包肯定是正…

AsyncLocalT在链路追踪中的应用

前言在项目生产中日志的记录是必不可少的&#xff0c;在.net项目中&#xff0c;要说日志组件&#xff0c;log4net绝对可有一席之地&#xff0c;随着公司业务的发展&#xff0c;微服务则必定无可避免。在跨服务中通过日志进行分析性能或者排查故障点&#xff0c;如何快速定位日志…

Windows运行命令大全

要打开Windows XP系统自带的程序,菜鸟一般是用鼠标点开始/程序(或桌面、快速启动)里的快捷方式,老鸟喜欢按下Win+R并输入运行命令。Windows XP的开始运行命令大全,其实都是C:\WINDOWS\system32下面的程序,只要在开始/运行/输入相应的程序名(命令)即可。对于常用运行命令…

【转】js老生常谈之this,constructor ,prototype

前言 javascript中的this,constructor ,prototype&#xff0c;都是老生常谈的问题&#xff0c;深入理解他们的含义至关重要。在这里&#xff0c;我们再来复习一下吧&#xff0c;温故而知新&#xff01; this this表示当前对象&#xff0c;如果在全局作用范围内使用this&#xf…

Linux+Oracle+12c+RAC+安装配置详细-GI安装

IP地址主机名用途实例名192.168.12.58oracle-rac03-db03 Public ip (节点1&#xff09;192.168.12.59oracle-rac04-db04Public ip(节点2&#xff09;192.168.12.73 rac03-db03-vipvip(节点1&#xff09;racdb3 asm1192.168.12.74rac04-db04-vipvip(节点2&#xff09;racdb4 …

android auto answer,Incoming call auto answer in android 4.0.3

问题I am working in Android technology last 1 years. Currently I want develop an application incoming call auto answer in Android 4.0.3 but in this version I am not getting any solution or cant find any api for this (ITelephony.aidl). Please suggest me.回答…

剑指offer之判断二叉树是不是平衡二叉树

1 问题 判断二叉树是不是平衡二叉树 平衡二叉搜索树&#xff08;Self-balancing binary search tree&#xff09;又被称为AVL树&#xff08;有别于AVL算法&#xff09;&#xff0c;且具有以下性质&#xff1a;它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1&#x…