Android Studio App开发之服务Service的讲解及实战(包括启动和停止,绑定与解绑,推送服务到前台实现音乐播放器,附源码)
创始人
2024-04-07 07:04:52
0

运行有问题或需要源码请点赞关注收藏后评论区留言~~~

一、服务的启动和停止

服务Service是Android的四大组件之一,它常用于页面的高级场合,这些系统服务平时几乎感觉不到它们的存在,却是系统不可或缺的重要组成部分。

既然Android自带了系统服务,App也可以拥有自己的服务,服务Service与活动Activity相比,不同之处在于没有对应的页面,相同之处在于都有生命周期 常用方法如下

1:onCreate 创建服务

2:onStart  开始服务

3:onStartCommand  开始服务

4:onDestroy 销毁服务

5:onBind 绑定服务

6:onUnbind 解除绑定

7:onRebind 重新绑定

点击启动服务和停止服务会调用相对应得方法  效果如下

 

代码如下

Java类 

package com.example.chapter11;import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.example.chapter11.service.NormalService;
import com.example.chapter11.util.DateUtil;@SuppressLint("StaticFieldLeak")
public class ServiceNormalActivity extends AppCompatActivity implements View.OnClickListener {private static TextView tv_normal;private Intent mIntent; // 声明一个意图对象private static String mDesc;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_service_normal);tv_normal = findViewById(R.id.tv_normal);findViewById(R.id.btn_start).setOnClickListener(this);findViewById(R.id.btn_stop).setOnClickListener(this);mDesc = "";// 创建一个通往普通服务的意图mIntent = new Intent(this, NormalService.class);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_start) { // 点击了启动服务按钮startService(mIntent); // 启动指定意图的服务} else if (v.getId() == R.id.btn_stop) { // 点击了停止服务按钮stopService(mIntent); // 停止指定意图的服务}}public static void showText(String desc) {if (tv_normal != null) {mDesc = String.format("%s%s %s\n", mDesc, DateUtil.getNowDateTime("HH:mm:ss"), desc);tv_normal.setText(mDesc);}}}

XML文件

二、服务的绑定与解绑 

服务启停除了上一小节介绍的普通方式,也就是绑定服务和解绑服务。对于服务来说,便要求提供粘合剂Binder指定服务的绑定关系,同时黏合剂指定服务的绑定关系,同时黏合剂还负责在两个组件或者在两个进程之间交流通信。效果如下

延迟绑定与立即绑定的生命周期区别在于

1:延迟绑定的首次绑定操作只触发onBind方法,再次绑定操作只触发onRebind方法

2:延迟绑定的解绑操作只触发onUnbind方法

代码如下

Java类 

package com.example.chapter11;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.util.Log;
import android.view.View;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.example.chapter11.service.BindDelayService;
import com.example.chapter11.util.DateUtil;public class BindDelayActivity extends AppCompatActivity implements View.OnClickListener {private static final String TAG = "BindDelayActivity";private static TextView tv_delay;private Intent mIntent; // 声明一个意图对象private static String mDesc;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_bind_delay);tv_delay = findViewById(R.id.tv_delay);findViewById(R.id.btn_start).setOnClickListener(this);findViewById(R.id.btn_bind).setOnClickListener(this);findViewById(R.id.btn_unbind).setOnClickListener(this);findViewById(R.id.btn_stop).setOnClickListener(this);mDesc = "";// 创建一个通往延迟绑定服务的意图mIntent = new Intent(this, BindDelayService.class);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_start) { // 点击了开始服务按钮startService(mIntent); // 启动服务} else if (v.getId() == R.id.btn_bind) { // 点击了绑定服务按钮boolean bindFlag = bindService(mIntent, mFirstConn, Context.BIND_AUTO_CREATE); // 绑定服务Log.d(TAG, "bindFlag=" + bindFlag);} else if (v.getId() == R.id.btn_unbind) { // 点击了解绑服务按钮if (mBindService != null) {unbindService(mFirstConn); // 解绑服务mBindService = null;}} else if (v.getId() == R.id.btn_stop) { // 点击了停止服务按钮stopService(mIntent); // 停止服务}}public static void showText(String desc) {if (tv_delay != null) {mDesc = String.format("%s%s %s\n", mDesc, DateUtil.getNowDateTime("HH:mm:ss"), desc);tv_delay.setText(mDesc);}}private BindDelayService mBindService; // 声明一个服务对象private ServiceConnection mFirstConn = new ServiceConnection() {// 获取服务对象时的操作public void onServiceConnected(ComponentName name, IBinder service) {// 如果服务运行于另外一个进程,则不能直接强制转换类型,否则会报错mBindService = ((BindDelayService.LocalBinder) service).getService();Log.d(TAG, "onServiceConnected");}// 无法获取到服务对象时的操作public void onServiceDisconnected(ComponentName name) {mBindService = null;Log.d(TAG, "onServiceDisconnected");}};}

XML文件

三、推送服务到前台

服务没有自己的布局文件,意味着无法直接在页面上展示服务信息,要想了解服务的运行情况,要么通过打印日志观察,要么通过某个页面的静态控件显示运行结果,然而活动页面有自身的生命周期,为此Android设计了一个让服务在前台运行的机制,也就是在手机的通知栏展示服务的画像,同时允许自己是否需要在通知栏显示 包括下面两个方法

1:startForeground 把当前服务切换到前台运行 即展示到通知栏

2:stopForeground 停止前台运行 即取消通知栏上的展示

 效果如下 连接了真机后会在 后台显示

 代码如下

Java类

package com.example.chapter11;import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.chapter11.service.MusicService;
import com.example.chapter11.util.ViewUtil;public class ForegroundServiceActivity extends AppCompatActivity implements View.OnClickListener {private EditText et_song;private Button btn_send_service;private boolean isPlaying = true; // 是否正在播放@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_foreground_service);et_song = findViewById(R.id.et_song);btn_send_service = findViewById(R.id.btn_send_service);btn_send_service.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_send_service) {if (TextUtils.isEmpty(et_song.getText())) {Toast.makeText(this, "请填写歌曲名称", Toast.LENGTH_SHORT).show();return;}// 创建一个通往音乐服务的意图Intent intent = new Intent(this, MusicService.class);intent.putExtra("is_play", isPlaying); // 是否正在播放音乐intent.putExtra("song", et_song.getText().toString());btn_send_service.setText(isPlaying?"暂停播放音乐":"开始播放音乐");startService(intent); // 启动音乐播放服务isPlaying = !isPlaying;}}}

XML文件

创作不易 觉得有帮助请点赞关注收藏~~~

相关内容

热门资讯

恒誉环保(688309)披露关... 截至2025年12月29日收盘,恒誉环保(688309)报收于23.88元,较前一交易日上涨2.58...
一场精准的“政策捕捉” 传鼎晖... 观点网 上海苏州河畔,一幢服务式公寓悄然易主,掀开了住房租赁行业生存逻辑变革的一角。 最新消息显示,...
从制度协同到产业共振 中越合作... [ 完善“边境口岸+产业园区”联动模式,将云南221.4亿元对越贸易额的增长势能延伸至内陆,形成“边...
武进不锈(603878)披露拟... 截至2025年12月29日收盘,武进不锈(603878)报收于10.16元,较前一交易日上涨2.21...
*ST熊猫因涉嫌违反证券法律法... 证券之星消息,12月30日*ST熊猫公开信息显示,熊猫金控股份有限公司因涉嫌违反证券法律法规,信息披...
7岁男孩偷吃邻居“变态辣”外卖... 七岁男孩小雨在小区玩耍时,发现邻居小张家门口的未拆外卖无人看管,便偷偷取走食用。此前小张多次遭遇外卖...
锂矿龙头,涉嫌内幕交易罪单位犯... 12月29日晚,锂矿龙头赣锋锂业发布公告称,公司于12月29日收到宜春市公安局的移送起诉告知书,因涉...
中国铀业聘任张仲斌为总法律顾问... 12月29日,中国铀业(001280)发布公告,王辉因工作安排原因辞去公司总法律顾问职务,辞任后仍担...
[视频]形势政策系列报告会第四... 央视网消息(新闻联播):形势政策系列报告会第四场报告会今天(12月29日)在北京举行。商务部党组书记...
联众(06899.HK)就前执... 格隆汇12月29日丨联众(06899.HK)公告,针对公司前执行董事兼前行政总裁伍国梁在其任职期间于...