8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

将 json 响应作为流进行处理

user25472259 2月前

71 0

我有一个 http 响应,其主体是 ByteReadChannel。我知道内容是 JSON 对象数组。我需要通过 JSON 对象的属性来过滤该响应主体。由于数组...

我有一个 http 响应,其主体是 ByteReadChannel 。我知道内容是一个 JSON 对象数组。我需要根据对象的属性过滤该响应主体 JSON 。由于该数组可能包含至少数千个对象,因此我希望避免将整个内容读入内存,应用我的过滤器并将结果发送到客户端。

我怎样才能将其转换 ByteReadChannel 为,比如说, Flow<MyJsonObject> 流上的过滤器? Flow 这只是一个例子,也许有更好的类可以使用......

附言:我用 Ktor .

帖子版权声明 1、本帖标题:将 json 响应作为流进行处理
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由user25472259在本站《kotlin》版块原创发布, 转载请注明出处!
最新回复 (0)
  • @somethingsomething:谢谢您的提示。但是,我一开始就错了,实际上只有一个 Json 对象具有要过滤的列表的属性。对我来说,这听起来很不一样,而且有点无法解决,对吗?

  • @Martin 这绝对是可能的,但是你需要自己编写逻辑,我从来没有用 ktor 做过这个,在解析方面,我只有用 jackson 做过这个的经验,使用流 API:

  • 我正在尝试创建简单的 Dice Roller JetPack Compose 应用程序。我创建了一个图像组合和按钮组合。每当我单击按钮时,日志语句都会显示按钮被单击,但我无法向上...

    我正在尝试创建简单的 Dice Roller JetPack Compose App。我创建了一个图像组合和按钮组合。每当我单击按钮时,日志语句都会显示按钮被单击,但我无法根据该数据更新骰子图像。我将附上我的代码以供将来参考。我做错了什么?

    package com.example.mydiceroller
    
    import android.os.Bundle
    import android.util.Log
    import androidx.activity.ComponentActivity
    import androidx.activity.compose.setContent
    import androidx.compose.foundation.Image
    import androidx.compose.foundation.layout.Arrangement
    import androidx.compose.foundation.layout.Column
    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.material3.Button
    import androidx.compose.material3.Text
    import androidx.compose.runtime.Composable
    import androidx.compose.ui.Alignment
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.res.painterResource
    import androidx.lifecycle.ViewModelProvider
    
    class MainActivity : ComponentActivity() {
    
        lateinit var mainViewModel: MainViewModel
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContent {
    
                mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
                Column(
                    modifier = Modifier
                        .fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center
                ) {
                    DiceImage(count = mainViewModel.count)
                    Button(onClick = {
                        mainViewModel.rollDice()
                    }
                    )
                    {
                        Text(text = "Let's Roll")
                    }
    
                }
            }
        }
    
    }
    
    @Composable
    fun DiceImage(count: Int) {
    
    
        Log.d("countValue", "${count}")
    
        var countId=when (count) {
            1 -> R.drawable.dice_1
            2 -> R.drawable.dice_2
            3 -> R.drawable.dice_3
            4 -> R.drawable.dice_4
            5 -> R.drawable.dice_5
            else -> R.drawable.dice_6
        }
        Image(
            painter = painterResource(id = countId), contentDescription = ""
        )
    }
    
    

    MainViewModel.kt

    package com.example.mydiceroller
    
    import android.util.Log
    import androidx.lifecycle.ViewModel
    import java.util.Random
    
    class MainViewModel : ViewModel() {
        var count: Int = 1
    
        fun rollDice(): Int {
            count = (Random().nextInt(6) + 1)
            Log.d("ViewModel", "ButtonClicked")
            return count
        }
    }
    
    

    我也尝试了 mutableStateOf 但失败了

  • anon 2月前 0 只看Ta
    引用 5

    问题是您的 Compose UI 无法检测到 count 视图模型中的变化。

    您需要存储 count 在 State 对象中。在可组合对象中,您可以使用类似这样的方法( by 解开 State,使其成为 Int,可以更轻松地使用):

    var count: Int by remember { mutableStateOf(1) }
    

    每当更新此变量时,都会触发重组,并且 UI 也会相应更新。由于您使用视图模型进行存储,因此 count 您需要使用 Flow:

    class MainViewModel : ViewModel() {
        private val _count = MutableStateFlow(1)
        val count = _count.asStateFlow()
    
        fun rollDice() {
            Log.d("ViewModel", "ButtonClicked")
            _count.value = (1..6).random()
        }
    }
    

    每当 rollDice 调用 count ,流程都会发生变化。您可以使用以下命令将可组合项中的此流程转换为 Compose State 对象 collectAsStateWithLifecycle (您需要 gradle 依赖项 androidx.lifecycle:lifecycle-runtime-compose ):

    setContent {
        val mainViewModel: MainViewModel = viewModel()
        val count: Int by mainViewModel.count.collectAsStateWithLifecycle()
    
        Column(
            modifier = Modifier
                .fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
        ) {
            DiceImage(count = count)
    
            Button(onClick = {
                mainViewModel.rollDice()
            }) {
                Text(text = "Let's Roll")
            }
        }
    }
    
  • 谢谢你的回答。无法运行整个代码,但在尝试了主要内容后对其进行了修改,最后用我答案中的这个“代码”得到了解决方案,扩展了你的解决方案

  • 感谢@Leviathan 提供的解决方案。我正在修改对我有用的@leviathan 解决方案

    setContent {
    //    mainViewModel = MainViewModel()
    //    mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
    //    val count = mainViewModel.count.collectAsStateWithLifecycle()
        val state = remember {
            MainViewModel()
        }
        val uiState by state.count.collectAsStateWithLifecycle()
        Log.d("DiceRollerMainActivity", "State Flow Count Value ${uiState}")
    
        val imageresource = when (uiState) {
            1 -> R.drawable.dice_1
            2 -> R.drawable.dice_2
            3 -> R.drawable.dice_3
            4 -> R.drawable.dice_4
            5 -> R.drawable.dice_5
            else -> R.drawable.dice_6
        }
        Log.d("DiceRollerMainActivity", "Image Resource Value ${imageresource}")
    
        Column(
            modifier = Modifier
                .fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
        ) {
            Image(
                painter = painterResource(id = imageresource),
                contentDescription = ""
            )
    
            Button(onClick = {
                state.rollDice()
            }) {
                Text(text = "Let's Roll")
            }
        }
    }
    
  • 请不要记住视图模型,那样就行不通了,例如当您更改设备的旋转时。让 Android 运行时处理视图模型的构造和生命周期,如我的答案所示。如果需要,您仍然可以提供工厂,但在这种情况下,我实际上建议您切换到 Hilt 之类的依赖项注入框架,让它为您处理一切。

  • 我正在使用前台服务类型作为位置来通过服务获取位置。它将每 2 分钟获取一次。服务启动和停止,2 分钟后它将再次启动和停止......

    我正在使用前台服务类型作为位置来通过服务获取位置。它将每 2 分钟获取一次。服务启动和停止,2 分钟后它将再次启动和停止,并在后台和前台继续运行。

    现在,我已经在开始之前给出了所有许可,

        <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
        <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    因此现在应用程序在后台并且 GPS 位置已关闭,下次启动前台服务位置更新时就会崩溃。

    Fatal Exception: java.lang.RuntimeException
    Unable to create service com.lystloc.utils.services.tracking.LocationUpdateService: java.lang.SecurityException: Starting FGS with type location callerApp=ProcessRecord{c137f46 23529:com.lystloc/u0a332} targetSDK=34 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_LOCATION] any of the permissions allOf=false [android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION] and the app must be in the eligible state/exemptions to access the foreground only permission
    

    提前致谢

  • 通过闹钟管理器我已重新安排每 5 分钟一次,位置已启用 = 可以在前台启动服务位置已启用 = 可以在后台启动服务位置已禁用 = 可以在前台启动服务位置已禁用 = 尝试在后台启动服务时崩溃

  • 在现代 Android 版本中,您无法从后台启动前台服务,除非在极少数情况下。上次我检查时,

返回
作者最近主题: