小编Fra*_*esc的帖子

确定主题何时没有订阅者

我想使用 PublishSubject 创建一个广播系统,后台任务将轮询某个端点并使用此主题定期广播结果。我想在第一个订阅者订阅主题时开始轮询,并在没有更多订阅者时停止轮询。如果新订阅者订阅,轮询应恢复。

我看到的唯一有点相关的函数是 hasObservers() 但它不太适合我的需求,我希望有订阅和取消订阅的回调 - 在前者上,如果没有说明,我会开始轮询,而在后者上我如果没有更多订阅者,将停止轮询;如何做到这一点?

android rx-java2

5
推荐指数
1
解决办法
1158
查看次数

Kotlin 协程和 SecurityException

我正在使用 Retrofit 的协程适配器,我看到,如果网络调用因 URL 不正确而失败,try/catch 块将捕获它,但是如果我删除 Internet 权限以便我们获得 SecurityException,应用程序反而会崩溃.

这是处理改造响应的代码:

override suspend fun execute(): Result<IpAddress> = try {
    val result = dataRepository.getIpAddress().await()
    Result.Success(result)
} catch (throwable: Throwable) {
    if (throwable is JobCancellationException) {
        throw throwable
    }
    Result.Error(throwable)
}
Run Code Online (Sandbox Code Playgroud)

存储库很简单

override suspend fun getIpAddress(): Deferred<IpAddress> = dataService.getIpAddress()
Run Code Online (Sandbox Code Playgroud)

interface DataService {
    @GET("/?format=json")
    fun getIpAddress(): Deferred<IpAddress>
}
Run Code Online (Sandbox Code Playgroud)

为什么像 UnknownHostException 这样的异常会被困住,而 SecurityException 会导致应用程序崩溃?

这是崩溃日志

09-09 12:27:25.467 12465 12495 E AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
09-09 12:27:25.467 12465 12495 E AndroidRuntime: Process: com.example.coroutines, PID: …
Run Code Online (Sandbox Code Playgroud)

android kotlin retrofit2 kotlinx.coroutines

5
推荐指数
1
解决办法
774
查看次数

将底部填充应用于导航栏

我正在使用BottomNavigation来自 Accompanist 的 ,我想将其绘制在导航栏后面。我从中获得了导航栏插图WindowInsets.navigationBars.getBottom,但该值太高并且产生了很大的间隙(参见图片)。如何获得导航栏的正确内容填充?

这是代码

@Composable
fun NavigationBar(
    navController: NavHostController,
    modifier: Modifier = Modifier,
) {
    val density = LocalDensity.current
    val bottomPadding = WindowInsets.navigationBars.getBottom(density).dp
    BottomNavigation(
        modifier = modifier,
        contentPadding = PaddingValues(bottom = bottomPadding),
    ) {
        // content omitted for brevity
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

windowinsets android-jetpack-compose jetpack-compose-accompanist

3
推荐指数
1
解决办法
8157
查看次数

使用 Kotlin DSL 配置 Protocol Buffers 0.9.x

我已将 Android 项目上的协议缓冲区版本从 0.8.x 更新到 0.9.1,但遇到了 gradle 同步错误。我已按照文档从文件中删除了导入build.gradle.kts,并且收到如下错误。

这是以下代码build.gradle.kts

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:21.0-rc-1"
    }
    generateProtoTasks {
        all().forEach { task ->
            task.plugins {
                create("java") {
                    option("lite")
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是错误,它指向该create("java") {行 - 如何使用 Kotlin DSL 配置协议缓冲区?

Caused by: org.gradle.api.UnknownDomainObjectException: ExecutableLocator with name 'java' not found.
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.createNotFoundException(DefaultNamedDomainObjectCollection.java:504)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getByName(DefaultNamedDomainObjectCollection.java:333)
        at com.google.protobuf.gradle.GenerateProtoTask$_getAllExecutableLocators_closure8.doCall(GenerateProtoTask.groovy:354)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at com.google.protobuf.gradle.GenerateProtoTask.getAllExecutableLocators(GenerateProtoTask.groovy:354)
        at com.google.protobuf.gradle.GenerateProtoTask.getReleaseExecutableLocators(GenerateProtoTask.groovy:350)
        at com.google.protobuf.gradle.GenerateProtoTask.access$0(GenerateProtoTask.groovy)
        at com.google.protobuf.gradle.GenerateProtoTask$_getExecutables_closure6.doCall(GenerateProtoTask.groovy:342)
        at com.google.protobuf.gradle.GenerateProtoTask$_getExecutables_closure6.call(GenerateProtoTask.groovy)
        at org.gradle.api.internal.provider.DefaultProvider.calculateOwnValue(DefaultProvider.java:72) …
Run Code Online (Sandbox Code Playgroud)

android protocol-buffers build.gradle gradle-kotlin-dsl

3
推荐指数
1
解决办法
1473
查看次数

在 Kotlin DSL 中为 gradle 定义维度

我正在将我的转换build.gradle为 Kotlin DSL。我在应用程序中有 2 个构建风格,但我不知道如何设置这些风格的维度:

flavorDimensions("type")

productFlavors {
    create("free") {
        buildConfigField("boolean", "IS_DONATE", false.toString())
        dimension = "type"
    }
    create("donate") {
        buildConfigField("boolean", "IS_DONATE", true.toString())
        dimension = "type"
    }
}
Run Code Online (Sandbox Code Playgroud)

dimension = "type"部分是失败; 你如何设置每种口味的维度?

android-gradle-plugin gradle-kotlin-dsl

1
推荐指数
1
解决办法
1481
查看次数

RxJava:数据库和远程服务器

我有一个要从本地数据库(如果可用)或其他远程服务器检索的对象列表。我正在使用 RxJava Observables(数据库使用 SqlBrite,远程服务器使用 Retrofit)。

我的查询代码如下:

Observable<List<MyObject>> dbObservable = mDatabase
            .createQuery(MyObject.TABLE_NAME,MyObject.SELECT_TYPE_A)
            .mapToList(MyObject.LOCAL_MAPPER);
Observable<List<MyObject>> remoteObservable = mRetrofitService.getMyObjectApiService().getMyObjects();

return Observable.concat(dbObservable, remoteObservable)
    .first(new Func1<List<MyObject>, Boolean>() {
                @Override
                public Boolean call(List<MyObject> myObjects) {
                    return !myObjects.isEmpty();
                }
            });
Run Code Online (Sandbox Code Playgroud)

我看到第一个 observable 正在运行并使用空列表命中第一个方法,但是改造后的 observable 没有运行,没有网络请求。如果我切换 observable 的顺序,或者只是返回远程 observable,它会按预期工作,它会访问远程服务器并返回对象列表。

为什么远程 observable 在这种情况下无法运行?当我首先将 observables 与 db 连接起来,然后再进行改造时,不会调用订阅者的 onNext、orError 和 onComplete 方法。

谢谢!

android rx-java retrofit2

0
推荐指数
1
解决办法
3302
查看次数

带有派生属性的Kotlin数据类

我有一个类,它是2个类的摘要.我把这个类变成了一个数据类,如下所示

data class Device(private val deviceModel: DeviceModel, private val deviceStatus: DeviceStatusModel) {
    val name = deviceModel.name ?: "Unknown"
    val id = deviceModel.id ?: -1
    val mode = when(deviceStatus.mode) {
        1 -> DEVICE_MODE_MANUAL
        2 -> DEVICE_MODE_AUTO
        3 -> DEVICE_MODE_OVERRIDE
        else -> DEVICE_MODE_MANUAL
    }
    val strength = deviceStatus.strength ?: 0
}
Run Code Online (Sandbox Code Playgroud)

但是,当我打印此类时,它不会打印名称,ID,模式和强度属性,它会打印设备模型和设备状态.有没有办法让类基于派生属性生成toString而不是构造函数?

android kotlin

0
推荐指数
2
解决办法
930
查看次数