`
gyht0808
  • 浏览: 115611 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Service

阅读更多
本节内容涉及到
一 什么是Service
二 如何使用Service
三 Service的生命周期

一 什么是Service

Service,看名字就知道跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。

两种启动Service的方式有所不同。这里要说明一下的是如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。

什么时候需要Service呢?比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。

二 如何使用Service

那接下来用代码来说明一下怎么使用Service,这里我们要讲的是Local Service也就是你自己的一个Service, 你也可以操作别的应用程序的service如果它允许你那么去做的话,这就设计到一个比较麻烦的东西interprocess communication (IPC),在不同的进程中通信的机制,这个我自己也还没有用过,等用了以后再跟大伙说说,通常情况下Local的就够用啦。

跟Activity一样首先你要写一个类继承自android.app.Service,在这里我叫他TestService
代码如下:

Java代码
package com.haric.tutorial; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.IBinder; 
import android.util.Log; 

public class TestService extends Service { 
private static final String TAG = "TestService"; 
private NotificationManager _nm; 

@Override 
public IBinder onBind(Intent i) { 
Log.e(TAG, "============> TestService.onBind"); 
return null; 
} 

public class LocalBinder extends Binder { 
TestService getService() { 
return TestService.this; 
} 
} 

@Override 
public boolean onUnbind(Intent i) { 
Log.e(TAG, "============> TestService.onUnbind"); 
return false; 
} 

@Override 
public void onRebind(Intent i) { 
Log.e(TAG, "============> TestService.onRebind"); 
} 

@Override 
public void onCreate() { 
Log.e(TAG, "============> TestService.onCreate"); 
_nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
showNotification(); 
} 

@Override 
public void onStart(Intent intent, int startId) { 
Log.e(TAG, "============> TestService.onStart"); 
} 

@Override 
public void onDestroy() { 
_nm.cancel(R.string.service_started); 
Log.e(TAG, "============> TestService.onDestroy"); 
} 

private void showNotification() { 
Notification notification = new Notification(R.drawable.face_1, 
"Service started", System.currentTimeMillis()); 

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
new Intent(this, TestServiceHolder.class), 0); 

// must set this for content view, or will throw a exception 
notification.setLatestEventInfo(this, "Test Service", 
"Service started", contentIntent); 

_nm.notify(R.string.service_started, notification); 
} 
} 
其中用到Notification是为了明显地表明Service存活的状态,跟demo的code学过来的,这样看上去直观一点,更多关于Notification的内容以后UI部分来写吧,现在就知道怎么使用就好了。

Java代码
@Override  
    public void onCreate() {   
        Log.e(TAG, "============> TestService.onCreate");   
        _nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);   
        showNotification();   
    }  


像这样,我在Service的几个生命周期函数中加了打印log的语句,方便测试。

Java代码
public class LocalBinder extends Binder { 
TestService getService() { 
return TestService.this; 
} 
}
这个方法是为了让调用者得到这个Service并操作它。
Service本身就这样简单了,你需要做什么就在onCreate和onStart里做好了,起个线程什么的。

再看一下它的调用者,TestServiceHolder

Java代码
package com.haric.tutorial; 
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.Toast; 

public class TestServiceHolder extends Activity { 
private boolean _isBound; 
private TestService _boundService; 

public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.test_service_holder); 
setTitle("Service Test"); 

initButtons(); 
} 

private ServiceConnection _connection = new ServiceConnection() { 
        public void onServiceConnected(ComponentName className, IBinder service) { 
        _boundService = ((TestService.LocalBinder)service).getService(); 
            
            Toast.makeText(TestServiceHolder.this, "Service connected", 
                    Toast.LENGTH_SHORT).show(); 
        } 

        public void onServiceDisconnected(ComponentName className) { 
            // unexpectedly disconnected,we should never see this happen. 
        _boundService = null; 
            Toast.makeText(TestServiceHolder.this, "Service connected", 
                    Toast.LENGTH_SHORT).show(); 
        } 
    }; 

private void initButtons() { 
Button buttonStart = (Button) findViewById(R.id.start_service); 
buttonStart.setOnClickListener(new OnClickListener() { 
public void onClick(View arg0) { 
startService(); 
} 
}); 

Button buttonStop = (Button) findViewById(R.id.stop_service); 
buttonStop.setOnClickListener(new OnClickListener() { 
public void onClick(View arg0) { 
stopService(); 
} 
}); 

Button buttonBind = (Button) findViewById(R.id.bind_service); 
buttonBind.setOnClickListener(new OnClickListener() { 
public void onClick(View arg0) { 
bindService(); 
} 
}); 

Button buttonUnbind = (Button) findViewById(R.id.unbind_service); 
buttonUnbind.setOnClickListener(new OnClickListener() { 
public void onClick(View arg0) { 
unbindService(); 
} 
}); 
} 

private void startService() { 
Intent i = new Intent(this, TestService.class); 
this.startService(i); 
} 

private void stopService() { 
Intent i = new Intent(this, TestService.class); 
this.stopService(i); 
} 

private void bindService() { 
Intent i = new Intent(this, TestService.class); 
bindService(i, _connection, Context.BIND_AUTO_CREATE); 
_isBound = true; 
} 

private void unbindService() { 
if (_isBound) { 
            unbindService(_connection); 
            _isBound = false; 
        } 
} 
} 
 

这里可以看到两种启动方法,start和bind,当然也是通过intent调用的,在intent中指明指定要启动的Service的名字,stop也一样 :
Java代码
private void startService() { 
Intent i = new Intent(this, TestService.class); 
this.startService(i); 
} 

private void stopService() { 
Intent i = new Intent(this, TestService.class); 
this.stopService(i); 
} 


对于bind的话,需要一个ServiceConnection对象

Java代码
private ServiceConnection _connection = new ServiceConnection() { 
        public void onServiceConnected(ComponentName className, IBinder service) { 
        _boundService = ((TestService.LocalBinder)service).getService(); 
            
            Toast.makeText(TestServiceHolder.this, "Service connected", 
                    Toast.LENGTH_SHORT).show(); 
        } 

        public void onServiceDisconnected(ComponentName className) { 
            // unexpectedly disconnected,we should never see this happen. 
        _boundService = null; 
            Toast.makeText(TestServiceHolder.this, "Service connected", 
                    Toast.LENGTH_SHORT).show(); 
        } 
    }
用来把Activity和特定的Service连接在一起,共同存亡,具体的生命周期细节下一段来讲。



三 Service的生命周期

Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy
我们有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。
1 通过startService
Service会经历 onCreate -> onStart stopService的时候直接onDestroy
如果是调用者(TestServiceHolder)自己直接退出而没有调用stopService的话,Service会一直在后台运行。下次TestServiceHolder再起来可以stopService。
2 通过bindService   
Service只会运行onCreate, 这个时候 TestServiceHolder 和TestService绑定在一起 TestServiceHolder 退出了,Srevice就会调用onUnbind->onDestroyed 所谓绑定在一起就共存亡了。

那有同学问了,要是这几个方法交织在一起的话,会出现什么情况呢?
一个原则是Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又bindService,Service只被创建一次。如果先是bind了,那么start的时候就直接运行Service的onStart方法,如果先是start,那么bind的时候就直接运行onBind方法。如果你先bind上了,就stop不掉了,对啊,就是stopService不好使了,只能先UnbindService, 再StopService,所以是先start还是先bind行为是有区别的。

看起来情况很多,不过我会把这次的代码包括上回Activity生命周期的研究代码都贴上了,希望你喜欢!大家有兴趣可以回去点点按钮看看log,多看几遍就知道了。


分享到:
评论

相关推荐

    不被杀死 service

    在安卓开发中,Service是一种用于在后台长时间运行的组件,它可以独立于用户界面执行任务,例如播放音乐、网络通信等。"不被杀死的 Service"指的是通过特定技术手段实现的Service,它能够在设备清理内存或者用户关闭...

    android service 简单实例源代码

    在Android开发中,Service是四大组件之一,它在后台运行,不与用户界面直接交互,常用于执行长时间的任务,如播放音乐、网络通信等。本篇文章将深入解析"android service 简单实例源代码",帮助你理解如何在Android...

    Service 启动与停止

    Service是Android系统中的一个重要组件,它负责在后台执行长时间运行的操作,不依赖于用户界面。在Android应用开发中,理解Service的启动与停止机制对于创建高效、稳定的后台服务至关重要。 一、Service概述 ...

    oracle service_name参数

    ### Oracle Service_Name 参数详解 #### 一、概述 在Oracle数据库管理中,`service_name`是一个重要的参数,它用于标识数据库实例所提供的服务名称。通过设置正确的`service_name`,可以确保客户端应用程序能够...

    Activity绑定Service(Kotlin)

    在Android应用开发中,Service是用于执行长时间运行操作的一个组件,而Activity是用户与应用交互的界面。将Activity与Service绑定是一种常见的通信方式,尤其在需要在后台运行任务且需要与用户界面保持交互时。本...

    通过Service播放音频的代码

    在Android开发中,Service是一种可以在后台长时间运行的组件,它不具有用户界面,但可以执行各种后台任务,如播放音乐。本示例的"通过Service播放音频的代码"旨在教你如何利用Service组件来实现音乐播放功能,使得...

    Java Service Wrapper使用总结

    Java Service Wrapper 使用总结 Java Service Wrapper 是一种可以将 Java 应用程序发布为可安装的服务的解决方案,它提供了一种简单的方式来将 Java 应用程序打包成一个独立的服务。下面是 Java Service Wrapper ...

    Android防止service多次执行startCommand

    在Android应用开发中,Service是四大组件之一,用于在后台长时间运行操作,比如播放音乐、网络通信等。然而,如果不加以控制,用户或者系统可能会多次启动同一个Service,导致不必要的资源消耗和服务的异常行为。本...

    android 录音机 service 例子

    在这个"android 录音机 service 例子"中,我们将深入探讨如何结合Service和MediaRecorder来创建一个能够后台录制音频的应用。 1. **Service基础** Service组件是Android应用开发中的关键部分,它可以在没有用户...

    Service向Activity传值(kotlin)

    在Android应用开发中,Service和Activity是两个非常重要的组件。Service用于在后台执行长时间运行的任务,而Activity则负责用户界面交互。在某些场景下,我们可能需要Service与Activity之间进行数据传递,例如本例中...

    ServiceNow 基础手册

    ServiceNow是当今流行的企业服务管理平台,它提供了一个集成的系统,允许用户在一个统一的界面中管理和自动化企业内部的各种工作流程。ServiceNow平台的基础手册涵盖了该平台的基本使用方法,包括如何导航、管理记录...

    Android-Service与Activity传值

    在Android应用开发中,`Service`和`Activity`是两个重要的组件。`Service`用于在后台执行长时间运行的任务,而`Activity`则负责用户界面交互。在某些场景下,我们可能需要在`Service`和`Activity`之间传递数据,比如...

    android多个activity和一个service通信

    在Android应用开发中,Activity和Service是两个关键组件。Activity代表用户界面,而Service则用于在后台执行长时间运行的任务,不直接与用户交互。在实际项目中,常常需要多个Activity与一个Service进行通信,比如本...

    【Android】开机自启动Service

    在Android系统中,Service是一种可以在后台长时间运行的组件,它不提供用户界面,但可以执行各种任务,如播放音乐、网络通信等。当设备启动时,我们有时希望某些Service能够自动启动,以便立即开始执行预定的任务,...

    用SQL语句解决Service Broker未启动的问题

    "解决 Service Broker 未启动的问题" Service Broker 是 SQL Server 中的一个组件,用于实现异步消息传递。它允许数据库管理员创建可靠的、可扩展的消息应用程序。但是,有时可能会遇到 Service Broker 未启动的...

    Android 多个service的action 相同冲突 验证demo

    在Android开发中,Service是应用程序组件之一,用于在后台执行长时间运行的操作,即使用户与应用程序交互界面不直接关联。在某些情况下,我们可能需要启动多个Service来执行不同的任务,但问题在于,如果这些Service...

    JavaService-2.0.10 32位,64位

    JavaService-2.0.10 是一个针对Java应用程序的服务包装工具,它允许开发者将Java应用程序作为Windows服务来运行。这个版本提供了32位和64位两种版本,以适应不同操作系统环境的需求。 在Windows系统中,服务是一种...

    Android之Service实现比较大小

    在Android开发中,Service是应用程序组件之一,用于在后台执行长时间运行的操作,即使用户与应用程序交互的界面已关闭。本篇文章将深入探讨Android中的Service,分析不同类型的Service及其特性,并对比它们之间的...

    Android系统在新进程中启动自定义服务过程(startService)的原理

    "Android系统在新进程中启动自定义服务过程(startService)的原理" 在 Android 系统中,startService 函数是一个非常重要的函数,它允许开发者在新进程中启动自定义服务。这项技术可以将一些计算型逻辑从主进程中...

    基于Service的简易音乐播放器

    在Android开发中,创建一个基于Service的简易音乐播放器是一个常见的练习,可以帮助开发者理解服务(Service)的概念以及如何处理多媒体播放。在这个项目中,我们关注的是Android 4.1.2版本,它提供了对基本多媒体...

Global site tag (gtag.js) - Google Analytics