当应用程序终止或关闭时,如何保留后台 android 服务 运行
How can i keep background android services running when app killed or closed
大家好
我有新闻应用程序,我想在每次更新时推送通知。
我使用 socketIO 从服务器监听,
Android 服务的问题 我想在关闭时保持服务 运行 |杀了。
当应用 运行 和我在 onStartCommand START_STICKY_COMPATIBILITY 中 return 时,我已经开始我的服务
它在应用程序关闭时正常工作,但小时服务被 OS 杀死但不会重新启动
有帮助吗?
注意:我忽略了应用程序的电池优化
我的服务Class:
class ServicesMain: Service() {
override fun onBind(p0: Intent?): IBinder? {
return null;
}
@SuppressLint("TrulyRandom")
fun handleSSLHandshake() {
try {
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate>? {
return null;
}
override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {}
})
val sc = SSLContext.getInstance("SSL")
sc.init(null, trustAllCerts, SecureRandom())
HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)
HttpsURLConnection.setDefaultHostnameVerifier { arg0, arg1 -> true }
} catch (ignored: Exception) {
}
}
@RequiresApi(Build.VERSION_CODES.O)
fun startSocket(){
handleSSLHandshake()
runBroadcast()
Log.d("TAG", "BroadcastReceiver: ")
Timer().schedule(object : TimerTask() {
override fun run() {
Log.d("TAG", "run: ${socket!!.connected()} ")
}
}, 0, 10000)
}
private var socket: Socket? = null;
@SuppressLint("RestrictedApi")
@RequiresApi(Build.VERSION_CODES.O)
fun runBroadcast() {
val myHostnameVerifier = HostnameVerifier { _, _ ->
return@HostnameVerifier true
}
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
})
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustAllCerts, null)
val okHttpClient = OkHttpClient.Builder()
.hostnameVerifier(myHostnameVerifier)
.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
.readTimeout(0, TimeUnit.MILLISECONDS).writeTimeout(0, TimeUnit.MILLISECONDS).build()
val options = IO.Options()
options.transports = arrayOf(Polling.NAME)
options.webSocketFactory = okHttpClient
options.callFactory=okHttpClient
options.secure = true
socket = IO.socket("https://....", options);
socket!!.connect().on("message", Emitter.Listener { args ->
val jsonObject = JSONObject(args[0] as String)
val calendarTime = jsonObject.getLong("starttime") - (Calendar.getInstance().timeInMillis)
println(calendarTime)
val builder = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
val data: Data.Builder = Data.Builder()
data.putStringArray("data", arrayOf<String>(jsonObject.getString("title"), jsonObject.getString("subject"), jsonObject.getString("id")))
val oneTimeWorkRequest = OneTimeWorkRequest.Builder(NotificationEvetns::class.java).setInputData(data.build()).setConstraints(builder.build())
.setInitialDelay(calendarTime, TimeUnit.MILLISECONDS).addTag(jsonObject.getString("id")).build()
this.let { WorkManager.getInstance(it).enqueue(oneTimeWorkRequest) }
})
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
Log.d("TAG", "onTaskRemoved: ")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("TAG", "onStartCommand: ")
return START_STICKY_COMPATIBILITY
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate() {
super.onCreate()
startSocket()
}
override fun onDestroy() {
super.onDestroy()
socket?.disconnect()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
Log.d("TAG", "onTrimMemory: ")
}
}
你不能,在 Android 的现代版本上不行。您可以创建一个最不可能被杀死的前台服务(在前台应用程序之外),但您不能指望它不会被杀死。而是编写您的代码,以便它不需要 - 主要是通过使用 WorkManager 来触发后台工作。除非你正在写一个服务器,在这种情况下我会说你应该使用另一个 OS,Android 是不合适的。
对于来自您提到的服务器的消息,我会使用 FCM 推送消息而不是长期的直接服务器连接。
大家好
我有新闻应用程序,我想在每次更新时推送通知。
我使用 socketIO 从服务器监听,
Android 服务的问题 我想在关闭时保持服务 运行 |杀了。
当应用 运行 和我在 onStartCommand START_STICKY_COMPATIBILITY 中 return 时,我已经开始我的服务
它在应用程序关闭时正常工作,但小时服务被 OS 杀死但不会重新启动
有帮助吗?
注意:我忽略了应用程序的电池优化
我的服务Class:
class ServicesMain: Service() {
override fun onBind(p0: Intent?): IBinder? {
return null;
}
@SuppressLint("TrulyRandom")
fun handleSSLHandshake() {
try {
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate>? {
return null;
}
override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {}
})
val sc = SSLContext.getInstance("SSL")
sc.init(null, trustAllCerts, SecureRandom())
HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)
HttpsURLConnection.setDefaultHostnameVerifier { arg0, arg1 -> true }
} catch (ignored: Exception) {
}
}
@RequiresApi(Build.VERSION_CODES.O)
fun startSocket(){
handleSSLHandshake()
runBroadcast()
Log.d("TAG", "BroadcastReceiver: ")
Timer().schedule(object : TimerTask() {
override fun run() {
Log.d("TAG", "run: ${socket!!.connected()} ")
}
}, 0, 10000)
}
private var socket: Socket? = null;
@SuppressLint("RestrictedApi")
@RequiresApi(Build.VERSION_CODES.O)
fun runBroadcast() {
val myHostnameVerifier = HostnameVerifier { _, _ ->
return@HostnameVerifier true
}
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
})
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustAllCerts, null)
val okHttpClient = OkHttpClient.Builder()
.hostnameVerifier(myHostnameVerifier)
.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
.readTimeout(0, TimeUnit.MILLISECONDS).writeTimeout(0, TimeUnit.MILLISECONDS).build()
val options = IO.Options()
options.transports = arrayOf(Polling.NAME)
options.webSocketFactory = okHttpClient
options.callFactory=okHttpClient
options.secure = true
socket = IO.socket("https://....", options);
socket!!.connect().on("message", Emitter.Listener { args ->
val jsonObject = JSONObject(args[0] as String)
val calendarTime = jsonObject.getLong("starttime") - (Calendar.getInstance().timeInMillis)
println(calendarTime)
val builder = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
val data: Data.Builder = Data.Builder()
data.putStringArray("data", arrayOf<String>(jsonObject.getString("title"), jsonObject.getString("subject"), jsonObject.getString("id")))
val oneTimeWorkRequest = OneTimeWorkRequest.Builder(NotificationEvetns::class.java).setInputData(data.build()).setConstraints(builder.build())
.setInitialDelay(calendarTime, TimeUnit.MILLISECONDS).addTag(jsonObject.getString("id")).build()
this.let { WorkManager.getInstance(it).enqueue(oneTimeWorkRequest) }
})
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
Log.d("TAG", "onTaskRemoved: ")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("TAG", "onStartCommand: ")
return START_STICKY_COMPATIBILITY
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate() {
super.onCreate()
startSocket()
}
override fun onDestroy() {
super.onDestroy()
socket?.disconnect()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
Log.d("TAG", "onTrimMemory: ")
}
}
你不能,在 Android 的现代版本上不行。您可以创建一个最不可能被杀死的前台服务(在前台应用程序之外),但您不能指望它不会被杀死。而是编写您的代码,以便它不需要 - 主要是通过使用 WorkManager 来触发后台工作。除非你正在写一个服务器,在这种情况下我会说你应该使用另一个 OS,Android 是不合适的。
对于来自您提到的服务器的消息,我会使用 FCM 推送消息而不是长期的直接服务器连接。