文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

详解Android中Service服务的基础知识及编写方法

2022-06-06 08:43

关注

首先,让我们确认下什么是service?

        service就是android系统中的服务,它有这么几个特点:它无法与用户直接进行交互、它必须由用户或者其他程序显式的启动、它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小哦。

那么,什么时候,我们需要使用service呢?
        我们知道,service是运行在后台的应用,对于用户来说失去了被关注的焦点。这就跟我们打开了音乐播放之后,便想去看看图片,这时候我们还不想音乐停止,这里就会用到service;又例如,我们打开了一个下载链接之后,我们肯定不想瞪着眼睛等他下载完再去做别的事情,对吧?这时候如果我们想手机一边在后台下载,一边可以让我去看看新闻啥的,就要用到service。

service分类:
       一般我们认为service分为两类,本地service和远程service。

      1. 本地service:顾名思义,那就是和当前应用在同一个进程中的service,彼此之间拥有共同的内存区域,所以对于某些数据的共享特别的方便和简单;

      2. 远程service:主要牵扯到不同进程间的service访问。因为android的系统安全的原因导致了我们在不同的进程间无法使用一般的方式共享数据。在这里android为我们提供了一个AIDL工具。(android interface description language)android接口描述语言。在后边我们将会对其进行详细的介绍。

Service启动流程
context.startService() 启动流程:
context.startService()  -> onCreate()  -> onStart()  -> Service running  -> context.stopService()  -> onDestroy()  -> Service stop

如果Service还没有运行,则android先调用onCreate(),然后调用onStart();
如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。
如果stopService的时候会直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。
所以调用startService的生命周期为:onCreate --> onStart (可多次调用) --> onDestroy

context.bindService()启动流程:
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。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

2016411141501384.gif (558×544)

service生命周期:

     和Activity相比,service的生命周期已经简单的不能再简单了,只有onCreate()->onStart()->onDestroy()三个方法。

Activity中和service有关的方法:

startService(Intent intent):启动一个service stopService(Intent intent) :停止一个service


如果我们想使用service中的一些数据或者访问其中的一些方法,那么我们就要通过下面的方法:

public boolean bindService(Intent intent, ServiceConnection conn, int flags) ; public void unbindService(ServiceConnection conn);

intent是跳转到service的intent,如 Intent intent = new Intent(); intent.setClass(this,MyService.class);


 
 @Override 
 public void onServiceConnected(ComponentName name, IBinder service) { 
  Log.i("通知", "链接成功!"); 
  MyBinder binder = (MyBinder)service; 
  MyService myService = binder.getMyService(); 
  int count = myService.getCount(); 
  Log.i("通知", "count="+count); 
 } 

   
使用service的步骤:


第一步:我们要继承service类,实现自己的service。

如果想要访问service中的某些值,我们通常会提供一个继承了Binder的内部类,通过onBund()方法返回给service请求。这里实际上巧妙的利用了内部类能够访问外部类属性的特点。        

第二步:在androidManifest.xml中进行注册,如:


<!-- 
 service配置开始
 -->
 <service android:name="MyService"></service>
<!-- 
 service配置结束
 -->

第三步:在activity中进行启动、绑定、解绑或者停止service。

(很多书上说,service与用户是不能交互的,其实这话很不正确,我们完全可以通过activity与service进行交互嘛!我觉得,确切的说法应该是service与用户不能进行直接的交互)。

例子
下边提供一个调用service听音乐的例子:


activity代码:


package cn.com.chenzheng_java; 
import cn.com.chenzheng_java.MyService.MyBinder; 
import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
 
public class ServiceActivity extends Activity implements OnClickListener{ 
 private Button button_start ; 
 private Button button_bind ; 
 private Button button_destroy ; 
 private Button button_unbind; 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.service); 
  button_start = (Button) findViewById(R.id.button1_service); 
  button_bind = (Button) findViewById(R.id.button2_service); 
  button_destroy = (Button) findViewById(R.id.button3_service); 
  button_unbind = (Button) findViewById(R.id.button4_service); 
  button_start.setOnClickListener(this); 
  button_bind.setOnClickListener(this); 
  button_destroy.setOnClickListener(this); 
  button_unbind.setOnClickListener(this); 
 } 
 private class MyServiceConnection implements ServiceConnection{ 
   
  @Override 
  public void onServiceConnected(ComponentName name, IBinder service) { 
   Log.i("通知", "链接成功!"); 
   MyBinder binder = (MyBinder)service; 
   MyService myService = binder.getMyService(); 
   int count = myService.getCount(); 
   Log.i("通知", "count="+count); 
  } 
  @Override 
  public void onServiceDisconnected(ComponentName name) { 
   Log.i("通知", "链接未成功!"); 
  } 
 } 
 private MyServiceConnection serviceConnection = new MyServiceConnection(); 
 @Override 
 public void onClick(View v) { 
  if(v == button_start){ 
   Intent intent = new Intent(); 
   intent.setClass(getApplicationContext(), MyService.class); 
   startService(intent); 
  } 
  if(v == button_bind){ 
   Intent intent = new Intent(); 
   intent.setClass(getApplicationContext(), MyService.class); 
   bindService(intent,serviceConnection , BIND_AUTO_CREATE); 
  } 
  if(v==button_destroy){ 
   Intent intent = new Intent(); 
   intent.setClass(getApplicationContext(), MyService.class); 
   stopService(intent); 
  } 
  if(v==button_unbind){ 
   unbindService(serviceConnection); 
  }   
 } 
} 

继承service的类:


package cn.com.chenzheng_java; 
import android.app.Service; 
import android.content.Intent; 
import android.media.MediaPlayer; 
import android.os.Binder; 
import android.os.IBinder; 
import android.util.Log; 
 
public class MyService extends Service { 
 MediaPlayer mediaPlayer; 
  
 @Override 
 public IBinder onBind(Intent intent) { 
  Log.i("通知", "service绑定成功!"); 
  return new MyBinder(); 
 } 
 @Override 
 public void onCreate() { 
  Log.i("通知", "service创建成功!"); 
  mediaPlayer = MediaPlayer.create(this, R.raw.aiweier); 
  mediaPlayer.setLooping(false); 
  super.onCreate(); 
 } 
 @Override 
 public void onDestroy() { 
  mediaPlayer.stop(); 
  Log.i("通知", "service销毁成功!"); 
  super.onDestroy(); 
 } 
 @Override 
 public void onRebind(Intent intent) { 
  Log.i("通知", "service重新绑定成功!"); 
  super.onRebind(intent); 
 } 
 @Override 
 public void onStart(Intent intent, int startId) { 
  mediaPlayer.start(); 
  Log.i("通知", "service start成功!"); 
  super.onStart(intent, startId); 
 } 
 @Override 
 public boolean onUnbind(Intent intent) { 
  mediaPlayer.stop(); 
  Log.i("通知", "service解绑成功!"); 
  return super.onUnbind(intent); 
 } 
 private int count = 100; 
 public int getCount() { 
  return count; 
 } 
 public void setCount(int count) { 
  this.count = count; 
 } 
 public class MyBinder extends Binder { 
   
  MyService getMyService() { 
   return MyService.this; 
  } 
 } 
} 

service.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"> 
 <Button android:text="启动" android:id="@+id/button1_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
 <Button android:text="绑定" android:id="@+id/button2_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
 <Button android:text="销毁" android:id="@+id/button3_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
 <Button android:text="解绑" android:id="@+id/button4_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
</LinearLayout> 

androidManifest.xml


<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  package="cn.com.chenzheng_java" 
  android:versionCode="1" 
  android:versionName="1.0"> 
 <uses-sdk android:minSdkVersion="8" /> 
 <application android:icon="@drawable/icon" android:label="@string/app_name"> 
  <activity android:name="ServiceActivity" 
     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配置开始 
 --> 
 <service android:name="MyService"></service> 
<!-- 
 service配置结束 
 --> 
 </application> 
 </manifest> 

  
最终效果图:

2016411141629351.gif (348×195)

您可能感兴趣的文章:Android中Service服务详解(二)Android中Service服务详解(一)android开发教程之开机启动服务service示例Android Service 服务不被杀死的妙招解析Android中如何做到Service被关闭后又自动启动的实现方法Android中实现开机自动启动服务(service)实例android中soap协议使用(ksoap调用webservice)在Android中 获取正在运行的Service 实例Android中使用IntentService创建后台服务实例Android中的Service相关全面总结Android Service服务不被停止详解及实现


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯