Android 自用 App保活——音乐播放保活适配8.0 (贼好用)

简介: 使用后台播放音乐的方式实现 app常驻内存。

又是好久没有积累东西了。惭愧,惭愧。。。手动哭泣。闲话说到这里,下面我介绍一种新的 App 保活方式哈,目前用小米家族手机 涵盖 Android 5.0 到 Android 8.1家族的测试。结论是,不主动干掉,是死不了的。但是主动干掉了,是活不了的。

之前介绍介绍了 双进程保活,我还大言不惭的 适配 8.0 。但是,从 Android 6.0 之后这个方法及其不好用,说死就死,华为,小米 分分钟 弄死笔者的 App 。 而且 最恶心的事情,居然 ANR 。 笔者对现在那些闭着眼睛 抄博客 的大佬实在不敢恭维了。对了,之前的笔记地址为:自己用到的Android 双服务保活(适配8.0), Android 6.0 以上不建议使用 !!!好了,下面说说,服务播放音乐,保活的基本原理吧。

一、保活原理

1、准备一首无声音乐(文末我会提供);

2、在认为可以进行保活的位置 进行激活服务 播放(笔者在MainActivity 内启动 服务);

3、在服务的 onCreate()方法内 初始化 MediaPlayer 对象;

4、将 onBind()方法返回值置空;

5、在 onStartCommand()方法内 开启线程 进行音乐播放(笔者选择播放 3s 之后进行了音乐暂停处理,放置部分 定制 os 出现锁屏 线程音乐播放界面,及其恶心,比如 miui);

6、在 onDestroy( ) 方法内进行关闭 播放器对象,移除播放器对象,重启本服务。

二、保活代码

/**
 * Content:后台播放音乐达到保活目的
 * Actor:韩小呆 ヾ(゚▽゚)ノ
 * Time:  2018/10/12 10:47
 * Update:
 * Time:
 */
public class SingASongService extends Service {
    private MediaPlayer mMediaPlayer;
    private Thread thread;

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

    @Override
    public void onCreate() {
        super.onCreate();
        MyThread myThread = new MyThread();
        thread = new Thread(myThread);
        mMediaPlayer = MediaPlayer.create(MainApplication.getInstance(), R.raw.no_kill);
        mMediaPlayer.setLooping(true);

        LogUtils.d("onCreate() 创建播放对象:" + mMediaPlayer.hashCode());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        thread.start();
        LogUtils.d("播放时 线程名称:" + thread.getName());
        return START_STICKY;
    }

    //开始、暂停播放
    private void startPlaySong() {
        if (mMediaPlayer == null) {
            mMediaPlayer = MediaPlayer.create(MainApplication.getInstance(), R.raw.no_kill);
            LogUtils.d("音乐启动播放,播放对象为: " + mMediaPlayer.hashCode());
            mMediaPlayer.start();
        } else {
            mMediaPlayer.start();
            LogUtils.d("音乐启动播放,播放对象为: " + mMediaPlayer.hashCode());
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (mMediaPlayer != null) {
            mMediaPlayer.pause();
            LogUtils.d("音乐启动播放,播放对象为: " + mMediaPlayer.hashCode());
            int progress = mMediaPlayer.getCurrentPosition();
            LogUtils.d("音乐暂停,播放进度:" + progress);
        }
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        mMediaPlayer.pause();
        LogUtils.d("恢复播放 时当前播放器对象:" + mMediaPlayer.hashCode());
        stopPlaySong();
        LogUtils.d("应用播放服务被杀死,正在重启");
        LogUtils.d("目标播放工作线程是否存活:" + thread.isAlive());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(new Intent(getApplicationContext(), SingASongService.class));
        } else {
            startService(new Intent(getApplicationContext(), SingASongService.class));
        }
    }

    //停止播放销毁对象
    private void stopPlaySong() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            LogUtils.d("音乐停止播放,播放对象为:" + mMediaPlayer.hashCode());
            LogUtils.d("音乐播放器是否在循环:" + mMediaPlayer.isLooping());
            LogUtils.d("音乐播放器是否还在播放:" + mMediaPlayer.isPlaying());
            mMediaPlayer.release();
            LogUtils.d("播放对象销毁,播放对象为:" + mMediaPlayer.hashCode());
            mMediaPlayer = null;
        }
    }

    class MyThread implements Runnable {

        @Override
        public void run() {
            startPlaySong();
        }
    }
}

为了方便判定 对象是否被消失,打印日志有点多,也方便,各位朋友验证。别 oom 啊。部分代码可以进行优化,比如说创建线程的方式,我只是为了方便验证吧,毕竟比较菜。

三、直接使用代码

public class SingASongService extends Service {
    
    private MediaPlayer mMediaPlayer;
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mMediaPlayer = MediaPlayer.create(MainApplication.getInstance(), R.raw.no_kill);
        mMediaPlayer.setLooping(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                startPlaySong();
            }
        }).start();
        return START_STICKY;
    }

    //开始、暂停播放
    private void startPlaySong() {
        if (mMediaPlayer == null) {
            mMediaPlayer = MediaPlayer.create(MainApplication.getInstance(), R.raw.no_kill);
            mMediaPlayer.start();
        } else {
            mMediaPlayer.start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (mMediaPlayer != null) {
            mMediaPlayer.pause();
        }
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        mMediaPlayer.pause();
        stopPlaySong();
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(new Intent(getApplicationContext(), SingASongService.class));
        } else {
            startService(new Intent(getApplicationContext(), SingASongService.class));
        }
    }

    //停止播放销毁对象
    private void stopPlaySong() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }
}

无声音乐

最后提醒部分小白,service 是需要注册的哦!ヾ(゚▽゚)ノ

最最后,给我读者有什么 特别的想法 可以随时 留言 提问。 还有,各位,可以点下小心心,或者是 加个关注啥的‧,::‧( ̄▽ ̄)/‧:‧°* 

相关文章
|
2月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
161 0
安卓项目:app注册/登录界面设计
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
134 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
3月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
211 2
|
3月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
113 3
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
77 10
|
2月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
281 0
|
3月前
|
调度 Android开发 UED
Android经典实战之Android 14前台服务适配
本文介绍了在Android 14中适配前台服务的关键步骤与最佳实践,包括指定服务类型、请求权限、优化用户体验及使用WorkManager等。通过遵循这些指南,确保应用在新系统上顺畅运行并提升用户体验。
228 6
|
3月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
4月前
|
API Android开发
Android P 性能优化:创建APP进程白名单,杀死白名单之外的进程
本文介绍了在Android P系统中通过创建应用进程白名单并杀死白名单之外的进程来优化性能的方法,包括设置权限、获取运行中的APP列表、配置白名单以及在应用启动时杀死非白名单进程的代码实现。
64 1
|
4月前
|
Android开发
Android 利用MediaPlayer实现音乐播放
本文提供了一个简单的Android MediaPlayer音乐播放示例,包括创建PlayerActivity、配置AndroidManifest.xml和activity_player.xml布局,以及实现播放和暂停功能的代码。
28 0
Android 利用MediaPlayer实现音乐播放