服务

活动(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)与服务进行通信,直接与服务交互。常用于需要长时间运行且需要频繁与应用组件交互的任务,比如播放音乐。

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

一定要先注册服务

服务

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

package com.example.myapplication;

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

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");
    }
}
普通服务

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(); // 暂停音乐
}
}
);
}