如何从运行在非活动类中的ktor路由API调用(例如/POST)中的另一个活动(registerForActivity)中获取结果?
背景:对于一个Android应用程序,我在一个非活动类HttpS中运行ktor服务器引擎'netty'erver.kt.我需要从ktor的路由'POST处理程序中调用另一个应用程序的活动,所以我从MainA传递'appCompatactive'ctivity.kt.这就完成了,只是因为,我假设,registerForActivityResult()依赖于UI/生命周期类。
按如下方式运行时会出现问题,因为registerForActivityResult()需要提前运行(如onCreate()?),我在这个非活动课上没有这样的课。此外,在返回ActivityResult时运行的回调需要调用ktor ApplicationCall的respond,它也是一个挂起函数。
class HttpServer(
private val applicationContext: AppCompatActivity
) {
private val logger = LoggerFactory.getLogger(HttpServer::class.java.simpleName)
private val server = createServer()
private fun ApplicationCall.startSaleActivityForResult() { // <====== *
val activityLauncherCustom =
applicationContext.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK || result.resultCode == Activity.RESULT_CANCELED) {
val transactionResultReturned = result.data
// Handle the returned result properly using transactionResultReturned
GlobalScope.launch {
respond(status = HttpStatusCode.OK, TransactionResponse())
}
}
}
val intent = Intent()
// Ignoring statements to create proper action/data intent
activityLauncherCustom.launch(intent) // <====== *
}
fun start() = server.start()
fun stop() = server.stop(0, 0)
private fun createServer(): NettyApplicationEngine {
return GlobalScope.embeddedServer(Netty) {
install(CallLogging)
install(ContentNegotiation) {
gson {
setPrettyPrinting()
}
}
routing {
route("/") {
post {
call.startSaleActivityForResult() // <====== *
}
}
}
}
}
private fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration>
CoroutineScope.embeddedServer(
factory: ApplicationEngineFactory<TEngine, TConfiguration>,
module: Application.() -> Unit
): TEngine {
val environment = applicationEngineEnvironment {
this.parentCoroutineContext = coroutineContext + parentCoroutineContext
this.log = logger
this.module(module)
connector {
this.port = 8081
}
}
return embeddedServer(factory, environment)
}
}
以上是我尝试的,但给出了以下错误。我没有在这个非活动类上创建onCreate。
Java语言lang.IllegalState例外:LifecycleOwner com。youtap。正常运行时间。MainActivity@38dcf06正在尝试在恢复当前状态时注册。生命周期所有者在启动之前必须调用register。
如有任何解决此问题的建议,我们将不胜感激。
为了解决您的问题并隐藏复杂性,您可以创建一个中间类来启动活动并等待结果的到来:
import kotlinx.coroutines.channels.Channel
class Repository(private val activity: MainActivity) {
private val channel = Channel<Int>(1)
suspend fun get(input: String): Int {
activity.activityLauncher.launch(input)
return channel.receive()
}
suspend fun callback(result: Int) {
channel.send(result)
}
}
您可以在MainActive
类中存储对存储库和活动启动器的引用:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
CoroutineScope(Dispatchers.IO).launch {
HttpServer(this@MainActivity).also { it.start() }
}
}
val activityLauncher = registerForActivityResult(MySecondActivityContract()) { result ->
GlobalScope.launch {
repository.callback(result!!)
}
}
val repository = Repository(this)
}
我的第二个活动和合同如下所示:
class ChildActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_child)
val result = Intent()
result.putExtra("name", 6666)
result.data = Uri.parse("http://mydata")
setResult(Activity.RESULT_OK, result)
finish()
}
}
class MySecondActivityContract : ActivityResultContract<String, Int?>() {
override fun createIntent(context: Context, input: String?): Intent {
return Intent(context, ChildActivity::class.java)
.putExtra("my_input_key", input)
}
override fun parseResult(resultCode: Int, intent: Intent?): Int? = when {
resultCode != Activity.RESULT_OK -> null
else -> intent?.getIntExtra("name", 42)
}
override fun getSynchronousResult(context: Context, input: String?): SynchronousResult<Int?>? {
return if (input.isNullOrEmpty()) SynchronousResult(42) else null
}
}
最简单的部分是路由处理程序:
routing {
route("/") {
post {
val result = (applicationContext as MainActivity).repository.get("input")
call.respondText { result.toString() }
}
}
}
此解决方案有效,但同时只处理一个请求,并且它不健壮,因为Active
可能会在HTTP服务器或存储库对象之前被销毁。
我已经创建了一个片段,当点击一个按钮时,会弹出一个类似对话框的ALTERVIEW。在该视图中包括谷歌登录按钮。当我连接到firebase并在startActivityForResult之后继续执行时,我需要重写onActivityResult方法。但弹出对应的类扩展了另一个对话框类,不能重写onActivityResult方法。当要重写时,它显示方法并没有从其超类错误重写方法。如何解决这个问题。以
在我的非活动类中,我请求了一个Fine location权限,但回调onRequestPermissionsResult“永远不会被调用”。现在我看到了一些与此相关的问题,但他们都认为请求是从活动或片段发出的,没有人考虑从非活动类发出请求。这是我的代码 这是onRequestPermissionResultCallback方法的实现 解决了:正如一些人提到的“activity”的onRequest
注意:这里有很多不同的答案,而且大多数在某个时候都是有效的。事实上,当Angular团队改变其路由器时,工作的方式已经改变了很多次。Router3.0版本将最终成为Angular中的路由器,它打破了许多这些解决方案,但提供了一个非常简单的解决方案。从RC.3开始,首选解决方案是使用,如本答案所示。 在Angular应用程序中(我写这篇文章的时候是2.0.0-Beta.0版本中的最新版本),如何确定
问题内容: 因此,我可以很好地做到这一点: 如果存在。我也可以高兴地做到这一点: 如果类文件存在于jar的适当部分中。简单的东西。但是我无法为自己的生活做这样的事情: 存在的地方和存在的地方(当然不包含MyClass)。 我会感到愚蠢吗? 问题答案: 可能:) 基本上,这只是在类路径和jar文件中包括(当前目录)。
问题内容: 我想获取方法的调用者类,即 在方法栏中,我需要获取类名称,然后找到了该方法: 但是,即使是,当我尝试调用它时,Eclipse 也会说: 访问限制:由于必需的库C:\ Program Files \ Java \ jre7 \ lib \ rt.jar的限制,无法访问类型为Reflection的方法getCallerClass() 还有其他选择吗? 问题答案: 你可以生成堆栈跟踪并使用S
本文向大家介绍如何使用python在Selenium中的工作簿中获取活动表?,包括了如何使用python在Selenium中的工作簿中获取活动表?的使用技巧和注意事项,需要的朋友参考一下 我们可以在Selenium的工作簿中获得活动表。Excel是电子表格,扩展名为.xlsx。一个excel工作簿有多个工作表,每个工作表都由行和列组成。 在所有工作表中,当我们访问一个称为活动工作表的特定工作表时。