这是个老生常谈的话题了,随着安卓版本的提升,google对这一块的管控是越来越严格,好了废话不多说了,直接说思路。
我现在的方案是:双进程拉活(Java层)+前台保活服务(一般情况下不建议使用,这种app对用户不友好),如果你需要那接着往下看代码:
注意:1到6和进程保活相关;7到10和androidx还有kotlin配置相关(你项目配置好了,就不用管7到10)
1.ForegroundCoreService(前台服务)
class ForegroundCoreService : Service() {
private lateinit var mForegroundNF: ForegroundNF
// private var mForegroundNF: ForegroundNF by lazy {
// ForegroundNF(this)
// }
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
super.onCreate()
mForegroundNF = ForegroundNF(this)
mForegroundNF.startForegroundNotification()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (null == intent) {
//服务被系统kill掉之后重启进来的
return START_NOT_STICKY
}
mForegroundNF.startForegroundNotification()
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
mForegroundNF.stopForegroundNotification()
super.onDestroy()
}
}
2.ForegroundNF(前台保活服务)
class ForegroundNF(private val service: ForegroundCoreService) : ContextWrapper(service) {
companion object {
private const val START_ID = 101
private const val CHANNEL_ID = "app_foreground_service"
private const val CHANNEL_NAME = "前台保活服务"
}
private var mNotificationManager: NotificationManager? = null
private var mCompatBuilder: NotificationCompat.Builder? = null
private val compatBuilder: NotificationCompat.Builder?
get() {
if (mCompatBuilder == null) {
val notificationIntent = Intent(this, MainActivity::class.java)
notificationIntent.action = Intent.ACTION_MAIN
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER)
notificationIntent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
//动作意图
val pendingIntent = PendingIntent.getActivity(
this, (Math.random() * 10 + 10).toInt(),
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
val notificationBuilder: NotificationCompat.Builder =
NotificationCompat.Builder(this, CHANNEL_ID)
//标题
notificationBuilder.setContentTitle(getString(R.string.app_name))
//通知内容
notificationBuilder.setContentText(getString(R.string.app_tips_content))
//状态栏显示的小图标
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher)
//通知内容打开的意图
notificationBuilder.setContentIntent(pendingIntent)
mCompatBuilder = notificationBuilder
}
return mCompatBuilder
}
init {
createNotificationChannel()
}
//创建通知渠道
private fun createNotificationChannel() {
mNotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//针对8.0+系统
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_LOW
)
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
channel.setShowBadge(false)
mNotificationManager?.createNotificationChannel(channel)
}
}
//开启前台通知
fun startForegroundNotification() {
service.startForeground(START_ID, compatBuilder?.build())
}
//停止前台服务并清除通知
fun stopForegroundNotification() {
mNotificationManager?.cancelAll()
service.stopForeground(true)
}
}
3.MainActivity(activity_main.xml你随便写)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Thread(Runnable {
try {
Thread.sleep(1200)
} catch (e: InterruptedException) {
e.printStackTrace()
}
startActivity(Intent(this@MainActivity, Main2Activity::class.java))
}).start()
}
}
4.Main2Activity(activity_main2.xml你随便写)
public class Main2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//双进程拉活(Java层)
startService(new Intent(this, ForegroundCoreService.class));
}
}
5.strings文件
BaoHuoJUEJIN
我可以让app存活更长久,请不要关闭我!
6.AndroidManifest.xml
7.app下面的build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.pop.baohuojuejin"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
8.项目下的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.50'
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
repositories {
//阿里云镜像地址:
//central仓和jcenter仓的聚合仓
maven { url 'https://maven.aliyun.com/repository/public' }
//google镜像地址
maven { url 'https://maven.aliyun.com/repository/google' }
google()
jcenter()
}
}
allprojects {
repositories {
//阿里云镜像地址:
//central仓和jcenter仓的聚合仓
maven { url 'https://maven.aliyun.com/repository/public' }
//google镜像地址
maven { url 'https://maven.aliyun.com/repository/google' }
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
9.gradle.properties文件
org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official
10.gradle版本配置
都看到这里了,给个小红心吧~