(1)掌握Service与Activity的区别;
(2)掌握Service的定义及使用;
(3)可以使用ServiceConnection 接口绑定一个Service;
(4)了解系统提供的Service程序。
Service是Android四大组件之一,和Activity最大的区别在于一个有界面,一个没有界面。



如果在程序中要实现Services的操作的话,需要定义一个Services类的子类,并且有这个子类复写相应的操作方法。

范例:定义后台服务
对于后台服务就是指我们Services程序,肯定是没有界面去显示的,就是在后台运行。
- <LinearLayout 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:orientation="vertical">
- <Button
- android:id="@+id/start"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="启动Services" />
- <Button
- android:id="@+id/stop"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="停止Services" />
- </LinearLayout>
-
关键肯定是要编写我们Services程序。
- package com.example.servicesproject;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
-
- public class MyServices extends Service {
- @Override
- public IBinder onBind(Intent intent) {//绑定Activity
- return null;
- }
- @Override
- public void onCreate() {//创建时调用
- System.out.println("============Service被创建============");
- }
- @Override
- public void onDestroy() {//销毁时调用
- System.out.println("============Service被销毁============");
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {//开始Services
- System.out.println("============Service启动============intent = " + intent + "startId="+startId);
- return Service.START_CONTINUATION_MASK;//表示Service继续执行
- }
- }
-
对于Service,本身并没有界面,只是提供了一个后台的操作,本身需要依靠Activity程序去启动。
- package com.example.servicesproject;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class ServicesActivity extends Activity {
- private Button start = null;
- private Button stop = null;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_services);
- this.start = (Button) super.findViewById(R.id.start);
- this.stop = (Button) super.findViewById(R.id.stop);
- this.start.setOnClickListener(new StartOnClickListenerImpl());
- this.stop.setOnClickListener(new StopOnClickListenerImpl());
- }
- private class StartOnClickListenerImpl implements OnClickListener {
- public void onClick(View v) {
- //启动Service
- ServicesActivity.this.startService(new Intent(ServicesActivity.this,MyServices.class));
- }
- }
- private class StopOnClickListenerImpl implements OnClickListener {
- public void onClick(View v) {
- //停止Service
- ServicesActivity.this.stopService(new Intent(ServicesActivity.this,MyServices.class));
- }
- }
- }
-
通过Activity程序去控制Service的开始和停止,既然Service程序是一个没有界面的Activity,那么肯定也需要在AndroidMainFest.xml里面进行配置。
- android:name="com.example.servicesproject.MyServices">


如果说一个Activity和Service要进行绑定的话,必须要使用到ServiceConnection这个接口,这个接口中有两个方法,一个是建立连接的时候使用,第二个是取消连接的时候使用, 但是一定要注意,连接是触发的操作中,还有一个IBinder接口对象。


既然IBinder是一个接口,那么这个接口中肯定存在大量的抽象方法,所以按照正常的思路肯定是会去覆写IBinder接口中所有的抽象方法,现在我们可以继承它,我们就可以覆写指定的方法。
- package com.example.servicesproject;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.Binder;
- import android.os.IBinder;
-
- public class MyServices extends Service {
- private IBinder myIBinder = new Binder(){
- @Override
- public String getInterfaceDescriptor() {//取得接口的描述信息
- return "MyServices.class";
- }
- };
- @Override
- public IBinder onBind(Intent intent) {//绑定Activity
- System.out.println("===========onBind==========intent="+intent);
- return myIBinder;
- }
-
- @Override
- public boolean onUnbind(Intent intent) {//解除绑定
- System.out.println("===========onUnbind==========intent="+intent);
- return super.onUnbind(intent);
- }
-
- @Override
- public void onRebind(Intent intent) {
- System.out.println("===========onRebind==========intent="+intent);
- super.onRebind(intent);
- }
-
- @Override
- public void onCreate() {//创建时调用
- System.out.println("============Service被创建============");
- }
- @Override
- public void onDestroy() {//销毁时调用
- System.out.println("============Service被销毁============");
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {//开始Services
- System.out.println("============Service启动============intent = " + intent + "startId="+startId);
- return Service.START_CONTINUATION_MASK;//表示Service继续执行
- }
- }
-
而后的Activity程序中增加一些操作按钮。
- package com.example.servicesproject;
-
- 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.os.RemoteException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class ServicesActivity extends Activity {
- private Button start = null;
- private Button stop = null;
- private Button bind = null;
- private Button unbind = null;
- private ServiceConnection serviceConnection = new ServiceConnection(){
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- try {
- System.out.println("==========连接到Service==========" + service.getInterfaceDescriptor());
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- System.out.println("=================取消Service=============");
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_services);
- this.start = (Button) super.findViewById(R.id.start);
- this.stop = (Button) super.findViewById(R.id.stop);
- this.start.setOnClickListener(new StartOnClickListenerImpl());
- this.stop.setOnClickListener(new StopOnClickListenerImpl());
- this.bind =(Button) super.findViewById(R.id.bind);
- this.unbind = (Button) super.findViewById(R.id.unbind);
- this.bind.setOnClickListener(new BindOnClickListenerImpl());
- this.unbind.setOnClickListener(new UNBindOnClickListenerImpl());
- }
- private class StartOnClickListenerImpl implements OnClickListener {
- public void onClick(View v) {
- //启动Service
- ServicesActivity.this.startService(new Intent(ServicesActivity.this,MyServices.class));
- }
- }
- private class StopOnClickListenerImpl implements OnClickListener {
- public void onClick(View v) {
- //停止Service
- ServicesActivity.this.stopService(new Intent(ServicesActivity.this,MyServices.class));
- }
- }
- private class BindOnClickListenerImpl implements OnClickListener{
- @Override
- public void onClick(View v) {
- //进行Service绑定
- ServicesActivity.this.bindService(new Intent(ServicesActivity.this,MyServices.class), ServicesActivity.this.serviceConnection, Context.BIND_AUTO_CREATE);
- }
- }
- private class UNBindOnClickListenerImpl implements OnClickListener{
- @Override
- public void onClick(View v) {
- //取消绑定
- ServicesActivity.this.unbindService(ServicesActivity.this.serviceConnection);
- }
- }
- }
-
此时的Activity程序就已经完成,下面我们来观察运行消息打印的流程。
·启动Service
- 01-27 01:07:36.243: INFO/System.out(487): ============Service被创建============
- 01-27 01:07:36.243: INFO/System.out(487): ============Service启动============intent = Intent { cmp=com.example.servicesproject/.MyServices }startId=1
·绑定Service
- 01-27 01:08:29.583: INFO/System.out(487): ===========onBind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
- 01-27 01:08:29.583: INFO/System.out(487): ==========连接到Service==========MyServices.class
通过打印,可以清楚的发现,出现了onBind之后,会返回到ServiceConnection中执行onServiceConnected()方法。
·如果不启动直接绑定
- 01-27 01:11:22.652: INFO/System.out(877): ============Service被创建============
- 01-27 01:11:22.652: INFO/System.out(877): ===========onBind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
- 01-27 01:11:22.672: INFO/System.out(877): ==========连接到Service==========MyServices.class
如果直接绑定,则直接调用OnCreate()、onBind()、ServiceConnection中的onServiceConnected()
·不停止,直接退出
- 01-27 01:12:39.733: I/System.out(877): ===========onUnbind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
- 01-27 01:12:39.733: I/System.out(877): ============Service被销毁============
不停止直接退出,会先取消绑定,再销毁。
·返回到Activity,同时再设置绑定
- 01-27 01:13:50.274: INFO/System.out(877): ============Service被创建============
- 01-27 01:13:50.274: INFO/System.out(877): ===========onBind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
- 01-27 01:13:50.292: INFO/System.out(877): ==========连接到Service==========MyServices.class
·解除绑定
- 01-27 01:14:19.702: INFO/System.out(877): ===========onUnbind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
- 01-27 01:14:19.702: INFO/System.out(877): ============Service被销毁============
也就是说,我们在操作之中,主应该注意的方法是:OnCreate()、onBind()、onUnbind(),onDestroy()。
虽然,以上的程序已经进行了绑定,但是还存在一个问题 。

定义一个空的接口,作为一个标识。
- public interface IService {
- }
此接口中不需要编写任何的操作方法。
- package com.example.servicesproject;
-
- import android.app.Service;
- import android.content.Intent;
- import android.os.Binder;
- import android.os.IBinder;
-
- public class MyServices extends Service {
- private IBinder myIBinder = new IBinderImpl();
- private class IBinderImpl extends Binder implements IService{
-
- @Override
- public String getInterfaceDescriptor() {//取得接口信息
- return "MyServices.class";
- }
-
- }
- @Override
- public IBinder onBind(Intent intent) {//绑定Activity
- System.out.println("===========onBind==========intent="+intent);
- return myIBinder;
- }
-
- @Override
- public boolean onUnbind(Intent intent) {//解除绑定
- System.out.println("===========onUnbind==========intent="+intent);
- return super.onUnbind(intent);
- }
-
- @Override
- public void onRebind(Intent intent) {
- System.out.println("===========onRebind==========intent="+intent);
- super.onRebind(intent);
- }
-
- @Override
- public void onCreate() {//创建时调用
- System.out.println("============Service被创建============");
- }
- @Override
- public void onDestroy() {//销毁时调用
- System.out.println("============Service被销毁============");
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {//开始Services
- System.out.println("============Service启动============intent = " + intent + "startId="+startId);
- return Service.START_CONTINUATION_MASK;//表示Service继续执行
- }
- }
-
大家一定要记住,IBinderImpl一定要是Binder和IService共同子类。
- package com.example.servicesproject;
-
- 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.os.RemoteException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class ServicesActivity extends Activity {
- private Button start = null;
- private Button stop = null;
- private Button bind = null;
- private Button unbind = null;
- private IService service = null;
- private ServiceConnection serviceConnection = new ServiceConnectionImpl();
- private class ServiceConnectionImpl implements ServiceConnection{
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- try {
- System.out.println("==========连接到Service==========" + service.getInterfaceDescriptor());
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- System.out.println("=================取消Service=============");
- }
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_services);
- this.start = (Button) super.findViewById(R.id.start);
- this.stop = (Button) super.findViewById(R.id.stop);
- this.start.setOnClickListener(new StartOnClickListenerImpl());
- this.stop.setOnClickListener(new StopOnClickListenerImpl());
- this.bind =(Button) super.findViewById(R.id.bind);
- this.unbind = (Button) super.findViewById(R.id.unbind);
- this.bind.setOnClickListener(new BindOnClickListenerImpl());
- this.unbind.setOnClickListener(new UNBindOnClickListenerImpl());
- }
- private class StartOnClickListenerImpl implements OnClickListener {
- public void onClick(View v) {
- //启动Service
- ServicesActivity.this.startService(new Intent(ServicesActivity.this,MyServices.class));
- }
- }
- private class StopOnClickListenerImpl implements OnClickListener {
- public void onClick(View v) {
- //停止Service
- ServicesActivity.this.stopService(new Intent(ServicesActivity.this,MyServices.class));
- }
- }
- private class BindOnClickListenerImpl implements OnClickListener{
- @Override
- public void onClick(View v) {
- //进行Service绑定
- ServicesActivity.this.bindService(new Intent(ServicesActivity.this,MyServices.class), ServicesActivity.this.serviceConnection, Context.BIND_AUTO_CREATE);
- }
- }
- private class UNBindOnClickListenerImpl implements OnClickListener{
- @Override
- public void onClick(View v) {
- if(null != ServicesActivity.this.service){
- //取消绑定
- ServicesActivity.this.unbindService(ServicesActivity.this.serviceConnection);
- ServicesActivity.this.service = null;
- }
-
- }
- }
- }
-
关键就是IBinder需要继承Binder还需要实现我们定义的空的接口。
·操作系统服务:服务的概念就是运行在后台之中,而且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:orientation="vertical">
-
-
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
-
如果需要取得系统服务,需要使用getSystemService(服务标记);
- package com.example.contextservice;
-
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.text.ClipboardManager;
-
- public class ContextServiceActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_context_service);
- ClipboardManager clipboardManager = (ClipboardManager)super.getSystemService(Context.CLIPBOARD_SERVICE);//取得剪贴板服务
- clipboardManager.setText("毛栗子");
- }
- }
-
这边就是直接使用了后台提供的服务。
范例:取得正在运行的Activity程序信息
- 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:orientation="vertical" >
-
- android:id="@+id/aclist"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
肯定是需要通过Activity程序取得所有信息并在ListView中显示。
- package com.example.activityrun;
-
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
-
- import android.app.Activity;
- import android.app.ActivityManager;
- import android.content.Context;
- import android.os.Bundle;
- import android.widget.ArrayAdapter;
- import android.widget.ListAdapter;
- import android.widget.ListView;
-
- public class MainActivity extends Activity {
- private ListView aclist = null;
- private ListAdapter adapter = null;
- private List
all = new ArrayList(); - private List
allTaskInfo = null;//所有任务信息 - private ActivityManager activityManager = null;//ActivityManager对象
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_main);
- this.aclist = (ListView) super.findViewById(R.id.aclist);
- this.activityManager = (ActivityManager)super.getSystemService(Context.ACTIVITY_SERVICE);
- this.listActivity();
- }
- public void listActivity(){
- this.allTaskInfo = this.activityManager.getRunningTasks(30);//取回30笔任务数据
- Iterator
it = this.allTaskInfo.iterator(); - while(it.hasNext()){
- ActivityManager.RunningTaskInfo task = it.next();
- this.all.add("【ID】"+task.id+"【NAME】"+task.baseActivity.getClassName());
- }
- this.adapter = new ArrayAdapter
(this,android.R.layout.simple_list_item_1,this.all); - this.aclist.setAdapter(this.adapter);
- }
- }
-
需要配置权限:
"android.permission.GET_TASKS"/>


如果说要取得服务信息,则直接修改以上的程序就可以了。如果是要取得所有的进程信息,我们也只需要修改以上的程序。
范例:取得网络信息

如果要获取手机讯息,我们肯定也需要使用列表完成显示。
- package com.example.activityrun;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.telephony.TelephonyManager;
- import android.widget.ArrayAdapter;
- import android.widget.ListAdapter;
- import android.widget.ListView;
-
- public class MainActivity extends Activity {
- private ListView telinfo = null;
- private ListAdapter adapter = null;
- private List
all = new ArrayList(); - private TelephonyManager telephonyManager = null;//ActivityManager对象
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_main);
- this.telinfo = (ListView) super.findViewById(R.id.aclist);
- this.telephonyManager = (TelephonyManager)super.getSystemService(Context.TELEPHONY_SERVICE);
- this.listActivity();
- }
- public void listActivity(){
- this.all.add(this.telephonyManager.getLine1Number()==null?"没有手机号码":"手机号:"+this.telephonyManager.getLine1Number());
- this.all.add(this.telephonyManager.getNetworkOperatorName()== null?"没有移动服务商":"移动服务商:"+this.telephonyManager.getNetworkOperatorName());
- if(this.telephonyManager.getPhoneType() == TelephonyManager.NETWORK_TYPE_CDMA){
- this.all.add("移动网络:CDMA");
- }else if(this.telephonyManager.getPhoneType() == TelephonyManager.NETWORK_TYPE_GPRS){
- this.all.add("移动网络:GPRS");
- }else{
- this.all.add("移动网络:未知");
- }
- this.all.add("是否漫游:"+(this.telephonyManager.isNetworkRoaming()?"是漫游":"非漫游"));
- this.adapter = new ArrayAdapter
(this,android.R.layout.simple_list_item_1,this.all); - this.telinfo.setAdapter(this.adapter);
- }
- }
-
权限:
"android.permission.READ_PHONE_STATE"/>
范例:操作WIFI


- 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:orientation="vertical" >
-
- android:id="@+id/mag"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- android:id="@+id/openWIFI"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="打开WIFI"/>
-
- android:id="@+id/closeWIFI"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="关闭WIFI"/>
-
- android:id="@+id/selectState"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="检查WIFI状态"/>
-
- package com.example.activityrun;
-
- import android.app.Activity;
- import android.content.Context;
- import android.net.wifi.WifiManager;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.TextView;
-
- public class MainActivity extends Activity {
- private TextView msg = null;
- private Button openWIFI = null;
- private Button closeWIFI = null;
- private Button selectState = null;
- private WifiManager wifiManager = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.activity_main);
- this.msg = (TextView) super.findViewById(R.id.mag);
- this.openWIFI = (Button) super.findViewById(R.id.openWIFI);
- this.closeWIFI = (Button) super.findViewById(R.id.closeWIFI);
- this.selectState = (Button) super.findViewById(R.id.selectState);
- this.wifiManager = (WifiManager)super.getSystemService(Context.WIFI_SERVICE);
- this.openWIFI.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- MainActivity.this.wifiManager.setWifiEnabled(true);//启动WIFI
- MainActivity.this.msg.setText("打开WIFI,状态:" + MainActivity.this.wifiManager.getWifiState());
- }
- });
- this.closeWIFI.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- MainActivity.this.wifiManager.setWifiEnabled(false);//关闭WIFI
- MainActivity.this.msg.setText("关闭WIFI,状态:" + MainActivity.this.wifiManager.getWifiState());
- }
- });
- this.selectState.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- MainActivity.this.msg.setText("检查WIFI,状态:" + MainActivity.this.wifiManager.getWifiState());
- }
- });
- }
- }
-
配置权限:
"android.permission.CHANGE_NETWORK_STATE"/> -
"android.permission.CHANGE_WIFI_STATE"/> -
"android.permission.ACCESS_WIFI_STATE"/>
1.3 小结
(1)Service是在后台运行的一种无界面的Activity程序;
(2)在Android系统之中提供了多种Service供用户使用;
-
相关阅读:
WSL2上Docker打包的镜像迁移到Ubuntu服务器上无法使用GPU
Django员工管理系统
字符集 - java案例分析
【安卓】Material Design
Java EE——线程(2)
学习ASP.NET Core Blazor编程系列一——综述
Java加密与解密
经常被人问起的API接口汇总,含免费次数
物通博联持续参与京东方(BOE)工厂数字化项目
ECMAScript6介绍及环境搭建
-
原文地址:https://blog.csdn.net/weixin_41830242/article/details/133829271
-
最新文章
-
沪漂五周年了:我越来越迷茫了
Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
MySQL-Seconds_behind_master的精度误差
[MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
Agent OS :五种驯服不确定性的范式
PortSwigger SQL注入LAB11
数据库即时编译JIT
[Begin]AI Learn Data Day 0
深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU