WorkManager 在后台抛出 NetworkOnMainThreadException
WorkManager throws NetworkOnMainThreadException when in background
我希望我的应用程序在使用 workmanager 时在后台阅读电子邮件和发送通知,我的工作管理器在执行几次后台任务后抛出 NetworkOnMainThreadException 后停止工作:
我想制作一个可靠的应用程序来为新收到的电子邮件发送通知,这意味着我需要它每 15 分钟永远执行一次。
你知道我怎样才能避免这个问题吗?
工作管理器class:
class WorkerMan(private val mContext: Context, workerParameters: WorkerParameters) :
Worker(mContext, workerParameters) {
@SuppressLint("RestrictedApi", "CheckResult")
val email = inputData.getString("email")
val password = inputData.getString("password")
@SuppressLint("RestrictedApi")
override fun doWork(): Result {
println("WorkManager: Work called")
println("WorkMananager time: " + LocalTime.now())
try {
// Thread.sleep(5000)
val session = Session.getDefaultInstance(Properties())
val store = session.getStore("imaps")
store.connect(
"mail.metropolitan.ac.rs",
993,
email,
password
)
val inbox = store.getFolder("INBOX")
inbox.open(Folder.READ_ONLY)
val messages = inbox.search(
FlagTerm(Flags(Flags.Flag.SEEN), false)
)
Arrays.sort(
messages
) { m1: Message, m2: Message ->
try {
return@sort m2.sentDate.compareTo(m1.sentDate)
} catch (e: MessagingException) {
throw RuntimeException(e)
}
}
Thread.sleep(1000)
println("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
println("WorkManager Started")
println("WorkMananager email: " + email)
val current = LocalTime.now()
println("WorkMananager time: " + current)
println("Messages amount: " + messages.size)
println("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
for (message in messages) {
// if (message.receivedDate.toInstant() >= Instant.now().minusMillis(1000 * 33 * 60)) {
if (true) {
// Thread.sleep(3000)
println("=====================================================")
println("NOTIFIKACIJA")
var title = ""
for (element in message.from) {
title += element.toString().substringAfter("<").substringBefore(">")
title += " "
}
println("Title :" + title)
println("Subject :" + message.subject)
println("Datum i vreme : " + message.receivedDate)
title.replace("[", "")
title.replace("]", "")
FirebaseMessaging.getInstance().token.addOnSuccessListener { token: String ->
if (!TextUtils.isEmpty(token)) {
Log.d("TAG", "retrieve token successful : $token")
try {
send(token, message.subject, title)
} catch (e: MessagingException) {
e.printStackTrace()
}
} else {
Log.w("TAG", "token should not be null...")
}
}.addOnFailureListener { e: Exception? -> }.addOnCanceledListener {}
.addOnCompleteListener { task: Task<String> ->
Log.v(
"TAG",
"This is the token : " + task.result
)
}
//
}
}
println("=====================================================")
Log.d("WorkManager", "Job finished")
}catch (e : Exception){
Log.d("WorkManager error", "doWork not executed")
Log.d("WorkManager error", "error: ")
Log.d("WorkManager error", e.printStackTrace().toString())
}
return Result.Success();
}
}
fun send(to: String?, body: String?, title: String?): String? {
try {
val apiKey =
"AAAA_Xfga4Q:APA91bH1cASekbIF7zSiqVkOtEJdQX2-qLO6yJp_iiTzYetdy6pRBl-uq28a27sdzDUvAUI51XO7IQaiKk_eccW0fTeFj8-4z7236mzoFaniTPMYR4Xmhzn5RYkAh-ON3tXKnELu7IEC"
val url = URL("https://fcm.googleapis.com/fcm/send")
val conn = url.openConnection() as HttpURLConnection
conn.doOutput = true
conn.requestMethod = "POST"
conn.setRequestProperty("Content-Type", "application/json")
conn.setRequestProperty("Authorization", "key=$apiKey")
conn.doOutput = true
val message = JSONObject()
message.put("to", to)
message.put("priority", "high")
val notification = JSONObject()
notification.put("title", title)
notification.put("body", body)
message.put("notification", notification)
val os = conn.outputStream
os.write(message.toString().toByteArray())
os.flush()
os.close()
val responseCode = conn.responseCode
println("\nSending 'POST' request to URL : $url")
println("Post parameters : $message")
println("Response Code : $responseCode")
println("Response Code : " + conn.responseMessage)
val `in` = BufferedReader(InputStreamReader(conn.inputStream))
var inputLine: String?
val response = StringBuffer()
while (`in`.readLine().also { inputLine = it } != null) {
response.append(inputLine)
}
`in`.close()
// print result
println(response.toString())
return response.toString()
} catch (e: Exception) {
Log.d("WorkManager error", "send not executed")
Log.d("WorkManager error", "error: ")
Log.d("WorkManager error", e.printStackTrace().toString())
}
return "error"
}
调度workmanager的函数:
@SuppressLint("RestrictedApi")
private fun startWorker(email: String, password: String) {
if (enableMailNotifications == 1) {
// val constraints = Constraints.Builder()
// .setRequiredNetworkType(NetworkType.CONNECTED).build()
val data = Data.Builder()
data.put("email", email)
data.put("password", password)
val build: PeriodicWorkRequest = PeriodicWorkRequest.Builder(
WorkerMan::class.java,
15,
TimeUnit.MINUTES,
15,
TimeUnit.MINUTES,
)
.addTag("WorkManager")
.setInputData(data.build())
// .setConstraints(constraints)
.build()
WorkManager.getInstance(this)
.enqueueUniquePeriodicWork("WorkManager", ExistingPeriodicWorkPolicy.REPLACE, build)
}else{
println("WorkManager not called: Mail Notifications are turned off")
}
}
编辑:完整 StackTraces:
我通过调用
解决了一个问题
FirebaseMessaging.getInstance().token.addOnSuccessListener
在 MainActivity 中并将令牌作为 WorkManager 的输入数据传递。
data.put("token", token)
并通过以下方式在 WorkManager class 中检索它:
val token = inputData.getString("token")
我希望我的应用程序在使用 workmanager 时在后台阅读电子邮件和发送通知,我的工作管理器在执行几次后台任务后抛出 NetworkOnMainThreadException 后停止工作: 我想制作一个可靠的应用程序来为新收到的电子邮件发送通知,这意味着我需要它每 15 分钟永远执行一次。 你知道我怎样才能避免这个问题吗?
工作管理器class:
class WorkerMan(private val mContext: Context, workerParameters: WorkerParameters) :
Worker(mContext, workerParameters) {
@SuppressLint("RestrictedApi", "CheckResult")
val email = inputData.getString("email")
val password = inputData.getString("password")
@SuppressLint("RestrictedApi")
override fun doWork(): Result {
println("WorkManager: Work called")
println("WorkMananager time: " + LocalTime.now())
try {
// Thread.sleep(5000)
val session = Session.getDefaultInstance(Properties())
val store = session.getStore("imaps")
store.connect(
"mail.metropolitan.ac.rs",
993,
email,
password
)
val inbox = store.getFolder("INBOX")
inbox.open(Folder.READ_ONLY)
val messages = inbox.search(
FlagTerm(Flags(Flags.Flag.SEEN), false)
)
Arrays.sort(
messages
) { m1: Message, m2: Message ->
try {
return@sort m2.sentDate.compareTo(m1.sentDate)
} catch (e: MessagingException) {
throw RuntimeException(e)
}
}
Thread.sleep(1000)
println("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
println("WorkManager Started")
println("WorkMananager email: " + email)
val current = LocalTime.now()
println("WorkMananager time: " + current)
println("Messages amount: " + messages.size)
println("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
for (message in messages) {
// if (message.receivedDate.toInstant() >= Instant.now().minusMillis(1000 * 33 * 60)) {
if (true) {
// Thread.sleep(3000)
println("=====================================================")
println("NOTIFIKACIJA")
var title = ""
for (element in message.from) {
title += element.toString().substringAfter("<").substringBefore(">")
title += " "
}
println("Title :" + title)
println("Subject :" + message.subject)
println("Datum i vreme : " + message.receivedDate)
title.replace("[", "")
title.replace("]", "")
FirebaseMessaging.getInstance().token.addOnSuccessListener { token: String ->
if (!TextUtils.isEmpty(token)) {
Log.d("TAG", "retrieve token successful : $token")
try {
send(token, message.subject, title)
} catch (e: MessagingException) {
e.printStackTrace()
}
} else {
Log.w("TAG", "token should not be null...")
}
}.addOnFailureListener { e: Exception? -> }.addOnCanceledListener {}
.addOnCompleteListener { task: Task<String> ->
Log.v(
"TAG",
"This is the token : " + task.result
)
}
//
}
}
println("=====================================================")
Log.d("WorkManager", "Job finished")
}catch (e : Exception){
Log.d("WorkManager error", "doWork not executed")
Log.d("WorkManager error", "error: ")
Log.d("WorkManager error", e.printStackTrace().toString())
}
return Result.Success();
}
}
fun send(to: String?, body: String?, title: String?): String? {
try {
val apiKey =
"AAAA_Xfga4Q:APA91bH1cASekbIF7zSiqVkOtEJdQX2-qLO6yJp_iiTzYetdy6pRBl-uq28a27sdzDUvAUI51XO7IQaiKk_eccW0fTeFj8-4z7236mzoFaniTPMYR4Xmhzn5RYkAh-ON3tXKnELu7IEC"
val url = URL("https://fcm.googleapis.com/fcm/send")
val conn = url.openConnection() as HttpURLConnection
conn.doOutput = true
conn.requestMethod = "POST"
conn.setRequestProperty("Content-Type", "application/json")
conn.setRequestProperty("Authorization", "key=$apiKey")
conn.doOutput = true
val message = JSONObject()
message.put("to", to)
message.put("priority", "high")
val notification = JSONObject()
notification.put("title", title)
notification.put("body", body)
message.put("notification", notification)
val os = conn.outputStream
os.write(message.toString().toByteArray())
os.flush()
os.close()
val responseCode = conn.responseCode
println("\nSending 'POST' request to URL : $url")
println("Post parameters : $message")
println("Response Code : $responseCode")
println("Response Code : " + conn.responseMessage)
val `in` = BufferedReader(InputStreamReader(conn.inputStream))
var inputLine: String?
val response = StringBuffer()
while (`in`.readLine().also { inputLine = it } != null) {
response.append(inputLine)
}
`in`.close()
// print result
println(response.toString())
return response.toString()
} catch (e: Exception) {
Log.d("WorkManager error", "send not executed")
Log.d("WorkManager error", "error: ")
Log.d("WorkManager error", e.printStackTrace().toString())
}
return "error"
}
调度workmanager的函数:
@SuppressLint("RestrictedApi")
private fun startWorker(email: String, password: String) {
if (enableMailNotifications == 1) {
// val constraints = Constraints.Builder()
// .setRequiredNetworkType(NetworkType.CONNECTED).build()
val data = Data.Builder()
data.put("email", email)
data.put("password", password)
val build: PeriodicWorkRequest = PeriodicWorkRequest.Builder(
WorkerMan::class.java,
15,
TimeUnit.MINUTES,
15,
TimeUnit.MINUTES,
)
.addTag("WorkManager")
.setInputData(data.build())
// .setConstraints(constraints)
.build()
WorkManager.getInstance(this)
.enqueueUniquePeriodicWork("WorkManager", ExistingPeriodicWorkPolicy.REPLACE, build)
}else{
println("WorkManager not called: Mail Notifications are turned off")
}
}
编辑:完整 StackTraces:
我通过调用
解决了一个问题FirebaseMessaging.getInstance().token.addOnSuccessListener
在 MainActivity 中并将令牌作为 WorkManager 的输入数据传递。
data.put("token", token)
并通过以下方式在 WorkManager class 中检索它:
val token = inputData.getString("token")