如何在Android Kotlin中包装异步Java库?

如何在Android Kotlin中包装异步Java库?,java,android,kotlin,listener,Java,Android,Kotlin,Listener,我想在Kotlin Android应用程序中使用Java库,但我对Kotlin比较陌生,需要一些建议。该库基本上如下所示: public interface Listener{ void onResult(Result res) } public class Client{ public Client(){} public void setListener(Listener l){} public void start(){} // Starts Thread(

我想在Kotlin Android应用程序中使用Java库,但我对Kotlin比较陌生,需要一些建议。该库基本上如下所示:

public interface Listener{
    void onResult(Result res)
}

public class Client{
    public Client(){}
    public void setListener(Listener l){}
    public void start(){} // Starts Thread(s) (so it's non-blocking), does some server calls, computes result, calls listener.onResult(res) after computation is finished.
    public void cancel(){} 
}
suspend fun doTheThing() : Result {
    val c = Client()
    try {
        //suspend until the listener fires or we're cancelled
        return suspendCancellableCoroutine {
            cont ->
            c.setListener {
                result -> cont.resume(result)
            }
            c.start()
        }
    } catch (e: Exception) {
        // If someone cancels the parent job, our job will complete exceptionally
        // before the client is done.  Cancel the client since we don't need it
        // anymore
        c.cancel()
        throw e
    }
}
是的,我知道,我可以直接调用函数并像在java中一样使用它,但这是Kotlin的方式吗? 我读到,执行类似的任务(使用异步函数,它接受回调参数)将通过将其包装在一个协程/挂起函数结构中来完成。
但是我不知道如何将其应用于我的问题(?)或者这是一种错误的方法?

如果您想将其变成一个很好的简单Kotlin挂起函数,它将如下所示:

public interface Listener{
    void onResult(Result res)
}

public class Client{
    public Client(){}
    public void setListener(Listener l){}
    public void start(){} // Starts Thread(s) (so it's non-blocking), does some server calls, computes result, calls listener.onResult(res) after computation is finished.
    public void cancel(){} 
}
suspend fun doTheThing() : Result {
    val c = Client()
    try {
        //suspend until the listener fires or we're cancelled
        return suspendCancellableCoroutine {
            cont ->
            c.setListener {
                result -> cont.resume(result)
            }
            c.start()
        }
    } catch (e: Exception) {
        // If someone cancels the parent job, our job will complete exceptionally
        // before the client is done.  Cancel the client since we don't need it
        // anymore
        c.cancel()
        throw e
    }
}

我看不到在你的界面中有一种方式可以让客户端指示失败。如果这是
结果的一部分
,那么你可能想在听众中把它变成一个例外

谢谢Matt,这很酷,但这也让我想到了一些进一步的问题。1.是否可以将初始化(构造函数和更有趣的setListener)移出函数?我还有一个库,在java中基本上是这样工作的:``Client c=new Client();Config con=new Config();con.listener=newlistener();/。。。其他配置成员c.initWithConfig(con);//比较重,所以每次都这样做并不好。e应该是什么?是否有特殊的JobCanceledException,或者异常是否正常?2:当您捕获到e时,会抛出异常,并且您已经完成了该操作,因此您希望取消客户端,而不管它是哪种类型的异常。1.是的,当然,然后您必须确保在完成此操作时断开侦听器的连接,这样它就不会在同一客户端上的下一个请求中被调用。但这不是Python,编译器需要e的类型;-)什么是最佳实践(例外、可丢弃、最终替换捕获)?哦,输入错误。我没有编译它。这只是个例外。对不起,我不明白。我该怎么做?你能不能用代码再详细解释一下?梅塔:我也不太会主动使用stackoverflow,在评论中讨论一下可以吗?