【问题标题】:Reading Mails with JavaMail in Activity/Fragment在 Activity/Fragment 中使用 JavaMail 读取邮件
【发布时间】:2021-07-01 21:14:56
【问题描述】:

我正在使用 android javamail 库 1.6.2。我正在尝试阅读邮件并将其作为片段中的自定义对象列表返回,以在回收站视图中显示它们。我用来阅读邮件的代码是:

fun readMails(host: String, port: String, 
              username: String, password: String): List<Mail>? {
    var folder: Folder? = null
    var store: Store? = null

    return try {
        val properties = Properties()
        properties[HOST] = host
        properties[PORT] = port
        properties[START_TLS] = "true"
        val session = Session.getDefaultInstance(properties)

        // Create IMAP store object and connect with the server
        store = session.getStore(PROTOCOL)
        store.connect(host, username, password)

        // Create folder object and open it in read-only mode
        folder = store.getFolder(FOLDER_TYPE)
        folder.open(Folder.READ_ONLY)

        // Fetch messages from the folder and print in a loop
        val messages = folder.messages

        val mails = messages.map {
            Mail(
                messageNumber = it.messageNumber,
                subject = it.subject,
                senders = it.from.toList().map { address ->
                    MailAddress(
                        type = address.type,
                    )
                },
                content = parseContent(it.content as Multipart)
            )
        }
        Log.d(TAG, "readMails: $mails")
        mails
    } catch (e: NoSuchProviderException) {
        Log.e(TAG, "NoSuchProviderException: ${e.localizedMessage}")
        null
    } catch (e: MessagingException) {
        Log.e(TAG, "MessagingException: ${e.localizedMessage}")
        null
    } catch (e: Exception) {
        Log.e(TAG, "Exception: ${e.localizedMessage}")
        null
    } finally {
        folder?.close(false)
        store?.close()
    }
}

在片段中,我正在尝试使用以下方式阅读邮件:

viewLifecycleOwner.lifecycleScope.launch {
    val emails = MailHelper.readMails(
        host = "",
        port = "",
        username = "",
        password = ""
    )
    mailAdapter.submitList(emails)
}

问题是我可以在控制台打印邮件,但我只能使用GlobalScope.launch {} 打印它们。如果我使用它,我无法在 recyclerview 中使用submitList() 显示适配器。如果我使用viewLifecycleOwner.lifecycleScope.launch {},我会不断收到android.os.NetworkOnMainThreadException

【问题讨论】:

    标签: android kotlin android-recyclerview jakarta-mail kotlin-coroutines


    【解决方案1】:

    您的问题源于viewLifecycleOwner.lifecycleScope 绑定到Dispatchers.Main.immediate 这仅限于应用程序'Main' 或'UI' 线程这意味着您的协程开始在UI 线程上执行并且您得到错误。

    要解决这个问题,您应该将 IO 调度程序传递给 launch 函数

    viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
        val emails = MailHelper.readMails(
            host = "",
            port = "",
            username = "",
            password = ""
        )
        mailAdapter.submitList(emails)
    }
    

    这将确保您的协程在分配给 IO 的线程池上执行,而不是在主线程上。

    注意:Dispatchers.IO 不能用于更新 UI,只有 UI 线程可以这样做

    【讨论】:

      猜你喜欢
      • 2014-04-27
      • 2017-11-09
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多