服务


活动(Activity)

  • 定义:Activity是一个可以通过用户直接交互的屏幕。它是用户与应用交互的窗口,可以包含各种视图(View)和视图组(ViewGroup)。
  • 生命周期:Activity具有丰富的生命周期,包括创建(onCreate)、启动(onStart)、运行(onResume)、暂停(onPause)、停止(onStop)和销毁(onDestroy)等状态。
  • 用户界面:Activity负责管理用户界面。每个Activity通常对应应用中的一个屏幕。
  • 交互:Activity可以直接与用户交互,响应用户的输入,如点击、滑动等。
  • 任务和回退栈:Activity通常被组织在任务和回退栈中,用户可以通过按下返回键来导航。

服务(Service)

  • 定义:Service是一个运行在后台,不提供直接用户界面的组件。它用于执行长时间运行的操作,或者为远程组件(如Activity)提供功能。
  • 生命周期:Service的生命周期比Activity简单,主要包括创建(onCreate)、绑定(onBind)、未绑定(onUnbind)、销毁(onDestroy)等状态。
  • 后台任务:Service适合执行不需要用户直接交互的后台任务,如播放音乐、处理文件、执行网络请求等。
  • 绑定和通信:Service可以通过绑定机制与Activity通信。Activity可以通过调用Service的bindService方法来绑定Service,并使用回调接口(Binder)与Service进行交互。
  • 前台和后台:Service可以运行在前台或后台。前台Service通常会显示一个持续的通知,以便用户知道Service正在运行。

服务周期

绑定式服务
  • 绑定服务(Bound Service):允许应用的组件(如Activity)与服务进行通信,直接与服务交互。常用于需要长时间运行且需要频繁与应用组件交互的任务,比如播放音乐。

首先与普通服务不一样,绑定服务需要有一个服务类,内部封装了我们需要的一些操作。通过服务与活动的通信进行操作。

一定要先注册服务

服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package  com.example.myapplication;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;

public class MusicService extends Service {

private final IBinder binder = new MusicBinder();
private MediaPlayer mediaPlayer;

// 创建一个Binder对象,用于Activity与Service通信
public class MusicBinder extends Binder {
MusicService getService() {
return MusicService.this;
}
}

@Override
public IBinder onBind(Intent intent) {
return binder;
}

@Override
public void onCreate() {
super.onCreate();
mediaPlayer = MediaPlayer.create(this, R.raw._apt); // 初始化音乐播放器
}

@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.release(); // 释放资源
}
}

// 播放音乐
public void playMusic() {
if (mediaPlayer != null && !mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
}

// 暂停音乐
public void pauseMusic() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}

// 停止音乐
public void stopMusic() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.prepareAsync(); // 为下一次播放做准备
}
}
}

交互的b 活动 内部注释很清楚 无非就是服务类封装了所有操作,调用服务类的方法和属性作为接口进行相关活动操作。 就是要绑定这一点有点特殊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.example.myapplication;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.graphics.Insets;

public class MainActivity_B extends AppCompatActivity {

// 创建私有服务对象
private MusicService musicService;
private boolean isBound = false;

// 定义一个ServiceConnection对象,绑定和解绑服务
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
musicService = binder.getService();
isBound = true;
}

@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main_b);

ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});

// 获取从 Activity A 传来的数据
String value = getIntent().getStringExtra("key");
// 处理数据 发送的数据
TextView myTextView1 = findViewById(R.id.textView3);
myTextView1.setText(value);

// 绑定播放按钮
ImageButton button_play = findViewById(R.id.imageButton);
ImageButton button_stop = findViewById(R.id.imageButton6);

button_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否绑定
if (isBound) {
musicService.playMusic(); // 播放音乐
}
}
});

button_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否绑定
if (isBound) {
musicService.pauseMusic(); // 暂停音乐
}
}
});
}

@Override
protected void onStart() {
super.onStart();
Log.d("ActivityLifecycle", "B_onStart called");
// 在开始的时候 绑定好服务
Intent intent = new Intent(this, MusicService.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.d("ActivityLifecycle", "B_onDestroy called");
// 在销毁时解绑服务,防止内存泄漏
if (isBound) {
unbindService(serviceConnection);
isBound = false;
}
}

@Override
protected void onStop() {
super.onStop();
Log.d("ActivityLifecycle", "B_onStop called");
// 在停止时解绑服务
if (isBound) {
unbindService(serviceConnection);
isBound = false;
}
}

@Override
protected void onPause() {
super.onPause();
Log.d("ActivityLifecycle", "B_onPause called");
}

@Override
protected void onResume() {
super.onResume();
Log.d("ActivityLifecycle", "B_onResume called");
}
}
普通服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class MainActivity_B extends AppCompatActivity {

private MediaPlayer mediaPlayer; // 播放器 对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main_b);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
// 创建一个 播放器绑定
mediaPlayer = MediaPlayer.create(this, R.raw._apt);
// 获取从 Activity A 传来的数据
String value = getIntent().getStringExtra("key");

// 处理数据 发送的数据
TextView myTextView1 = findViewById(R.id.textView3);
// 接收a发来的 讯息
myTextView1.setText(value);
// 绑定播放按钮
ImageButton button_play=findViewById(R.id.imageButton);
ImageButton button_stop=findViewById(R.id.imageButton6);
button_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否没在播放音乐
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start(); // 播放音乐
}
}
});
button_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 判断是否在播放音乐
if (mediaPlayer.isPlaying())
mediaPlayer.pause(); // 暂停音乐
}
});
}

文章作者: K1T0
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 K1T0 !
  目录