我在业余时间实现了一个Android应用程序(在Kotlin中,但这与问题无关),我尝试使用android jetpack和新库。我有一个带有导航抽屉的活动。我尝试遵循示例向日葵应用程序。它在主要活动中使用以下组合来启用导航抽屉背后的逻辑:
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
setSupportActionBar(findViewById(R.id.toolbar))
setupActionBarWithNavController(navController, appBarConfiguration)
Run Code Online (Sandbox Code Playgroud)
关于此代码的注意事项:在导航抽屉中单击时,此代码将自动导航到正确的片段,然后关闭抽屉并保持选中状态,等等。所有这些样板代码。那很整洁,也可以。据我了解,导航抽屉菜单项的ID必须与导航图中的片段的ID匹配,并以此方式进行连接。
我遇到的问题:当我使用导航抽屉转到导航图的起始片段以外的任何片段时,它将显示一个后退按钮,而不是汉堡包项目。那不是我所期望的,我希望它仍然是汉堡包,因为导航抽屉用于在相同级别的视图之间导航,而不是彼此嵌套,对吗?如果我通过单击片段中的元素(例如,列表->详细信息)导航到任何片段的子片段,则希望有一个后退按钮,但是如果我使用导航抽屉进行导航,则不会。
现在,我将问题追溯到生成AppBarConfiguration器,该生成器读取了带有导航图的构造函数The NavGraph whose start destination should be considered the only top level destination.,通过覆盖AppBarConfiguration以返回不同的顶级目的地(而不只是导航图的起始目的地),我可以很轻松地解决此问题。
但是我的问题是,为什么会有这种行为默认?是虫子吗?如果我不这样做,是否会违反Google的某些设计准则?导航抽屉中的每个元素是否都应该与我期望的处于同一水平?我是否想使用其他解决方案?
android navigation-drawer android-navigation android-jetpack
我正在尝试模拟 Android 上下文以从资源 id 返回字符串。但是,我在将存根与调用匹配时遇到问题,我认为这是因为可变参数。然而,我是模拟新手,所以我可能会错过一些非常简单的东西。
我这样嘲笑上下文:
val context = mockk<Context>()
every { context.getString(any(), any()) } returns stringToReturn
Run Code Online (Sandbox Code Playgroud)
但是当在对象上调用 getString 时,它会抛出以下异常:
io.mockk.MockKException: no answer found for: Context(#1).getString(2131689544, [])
Run Code Online (Sandbox Code Playgroud)
如果它很重要,我会在被测试的类中调用与此类似的函数。formatArgs 可以为空,但不必为空:
protected fun foo(stringResource: Int, vararg formatArgs: Any) {
val s = context.getString(errorMessageStringResource, *formatArgs)
Run Code Online (Sandbox Code Playgroud)
知道我该如何解决这个问题吗?
您可以在此处检查项目并重现异常:Github Project
我有以下类属性:
class Properties {
private Boolean enabled;
public Boolean getEnabled() {
return enabled;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我编写以下代码,SonarLint 会在 if 条件上给我一个警告,说“在此处使用原始布尔表达式。”。
if (!properties.getEnabled()) {
return true;
}
// more code
Run Code Online (Sandbox Code Playgroud)
将 if 条件更改为以下内容会关闭警告。但那不太可读,那不可能是 SonarLint 想要的,或者?
if (properties.getEnabled().equals(Boolean.FALSE)) {
return true;
}
// more code
Run Code Online (Sandbox Code Playgroud)
SonarLint 到底想让我在这里做什么?问题是什么?
我有一堆列作为csv文件中的字符串数组.现在我想解析它们.由于这种解析需要日期解析和其他不那么快的解析技术,我正在考虑并行性(我计时,它需要一些时间).我的简单方法:
Stream.of(columns).parallel().forEach(column ->
result[column.index] = parseColumn(valueCache[column.index], column.type));
Run Code Online (Sandbox Code Playgroud)
列包含的ColumnDescriptor元素只有两个属性,即要解析的列索引和定义如何解析它的类型.没有其他的.result是一个Object数组,它接受结果数组.
问题是现在解析函数抛出ParseException,我进一步处理调用堆栈.既然我们在这里并行,它就不能被抛出.处理这个问题的最佳方法是什么?
我有这个解决方案,但我有点畏缩阅读它.什么是更好的方法呢?
final CompletableFuture<ParseException> thrownException = new CompletableFuture<>();
Stream.of(columns).parallel().forEach(column -> {
try {
result[column.index] = parseColumn(valueCache[column.index], column.type);
} catch (ParseException e) {
thrownException.complete(e);
}});
if(thrownException.isDone())
//only can be done if there is a value set.
throw thrownException.getNow(null);
Run Code Online (Sandbox Code Playgroud)
注意:我不需要所有例外.如果我按顺序解析它们,我也只会得到一个.这样就可以了.
java parallel-processing exception-handling java-8 java-stream
我想为我的 android 应用程序编写测试。有时 viewModel 会使用 Kotlins 协程启动函数在后台执行任务。这些任务在 androidx.lifecycle 库提供的 viewModelScope 中执行。为了仍然测试这些功能,我用 Dispatchers.Unconfined 替换了默认的 android Dispatchers,它同步运行代码。
至少在大多数情况下。使用 suspendCoroutine 时, Dispatchers.Unconfined 不会被挂起并稍后恢复,而是会简单地返回。的文档Dispatchers.Unconfined揭示了原因:
[Dispatchers.Unconfined] 让协程在相应挂起函数使用的任何线程中恢复。
所以根据我的理解,协程实际上并没有被挂起,而是之后的异步函数的其余部分suspendCoroutine在调用continuation.resume. 因此测试失败。
例子:
class TestClassTest {
var testInstance = TestClass()
@Test
fun `Test with default dispatchers should fail`() {
testInstance.runAsync()
assertFalse(testInstance.valueToModify)
}
@Test
fun `Test with dispatchers replaced by Unconfined should pass`() {
testInstance.DefaultDispatcher = Dispatchers.Unconfined
testInstance.IODispatcher = Dispatchers.Unconfined
testInstance.runAsync()
assertTrue(testInstance.valueToModify)
}
@Test
fun `I need to also test some functions that …Run Code Online (Sandbox Code Playgroud) 我是 JS 和 Kotlin/JS 的新手。我有以下来自示例的黑曜石插件的最小工作 Javascript 代码。它按预期工作:
var obsidian = require('obsidian');
class SomePlugin extends obsidian.Plugin {
onload() {
new obsidian.Notice('This is a notice!');
}
}
module.exports = Plugin;
Run Code Online (Sandbox Code Playgroud)
我希望使用 Kotlin 来扩展这个插件,因为我了解这种语言,但是将其转换为 Kotlin/JS 时遇到一些问题。到目前为止我的方法:
可运行的项目可以在 Github 上找到。运行gradle build生成构建文件夹。它会在浏览器步骤中失败,但该步骤不是必需的。构建完成后,可以在 .js 文件中找到生成的 js 文件build\js\packages\main\kotlin\main.js。
主程序.kt
@JsExport
class SomePlugin: Plugin() {
override fun onload() {
Notice("This is a notice!")
}
}
@JsModule("obsidian")
@JsNonModule // required by the umd moduletype
external open class Component {
open fun …Run Code Online (Sandbox Code Playgroud) 我有一个Kotlin Android应用程序。有一个函数可以从后端加载合成并将其返回给回调:
getCompositons(callback: (Array<Composition>) -> Unit)
Run Code Online (Sandbox Code Playgroud)
我怎样才能使用嘲笑模拟回调。这样我就可以执行以下操作:
var callback = //mockito mock
getCompositons(callback)
verify(callback, timeout(10000)).apply()
Run Code Online (Sandbox Code Playgroud)
我读到lambda与Java类型的函数匹配,因此我认为apply可能是调用的方法。也许我可以模拟一个函数并使用它?但是Kotlin函数接口似乎只有一种返回类型,没有参数。java.util.Function说未解决的参考函数。
任何帮助表示赞赏。
请有人帮我!我快疯了,这应该工作。尝试构建Android项目时,出现以下错误消息:
Android resource linking failed
/Users/slehrbaum/StudioProjects/OneNightComps/Android/app/build/intermediates/incremental/mergeDebugResources/stripped.dir/layout/fragment_login.xml:17: error: attribute errorText (aka lehrbaum.de.onenightcomps:errorText) not found.
error: failed linking file resources.
Run Code Online (Sandbox Code Playgroud)
错误消息确实提到了errorText属性。我以这种方式在xml中使用errorText属性(此处为完整xml):
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/usernameField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/username"
app:hintEnabled="true"
app:errorEnabled="true"
app:errorText="Hi"
>
<!--app:errorText="Please provide a username."-->
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="username"
android:inputType="text"
android:text="@={viewModel.username}"
/>
</com.google.android.material.textfield.TextInputLayout>
Run Code Online (Sandbox Code Playgroud)
这是我在Kotlin文件(此处为完整文件)中定义errorText的方式:
object ViewDataBindingExtensions {
@JvmStatic
@BindingAdapter("errorText")
fun bindErrorText(textInputLayout: TextInputLayout, errorText: String) {
textInputLayout.error = errorText
}
}
Run Code Online (Sandbox Code Playgroud)
我只是不明白为什么会这样。我可以在布局文件中输入某种类型的导入信息,以说明BindingAdapter的位置吗?我的Gradle文件有问题吗?在这个问题上,我将它与GitHub项目进行了比较, 这个问题显然已经解决了,我看不出我的项目有什么区别。根据答案,我应该将Kotlin-kapt插件添加到我的Gradle构建中。我还浏览了项目的其余部分并进行了比较。无济于事。您可以在这里找到我的整个build.gradle文件以及该项目的其余部分。
请帮我!
问题介绍:
在使用MediatorLiveDataandroid自带的android jetpack的时候,我发现自己经常从各个源调用同一个函数。例如,这可能是因为,每当更新一个来源时,我都必须检查它是否有影响,或者另一个来源是否更重要。代码示例(Kotlin,但不重要):
val isHovered = MutableLiveData<Boolean>()
val isSelected = MutableLiveData<Boolean>()
val color = MediatorLiveData<Int>().apply {
addSource(isHovered) { updateColor() }
addSource(isSelected) { updateColor() }
}
fun updateColor() {
if (isHovered.value == true)
color.value = Color.GREEN
else if (isSelected.value == true)
color.value = Color.RED
else
color.value = Color.GRAY
}
Run Code Online (Sandbox Code Playgroud)
悬停时项目为绿色,选中时为红色,未悬停时为红色,否则为灰色。当 isSelected 变为 true 时,在将颜色更改为红色之前,我还需要检查它是否处于悬停状态。此外,当 isHovering 更改为 false 时,我需要在将颜色更改为灰色之前检查它是否被选中。所以最简单的是一个函数,它考虑了所有变量并相应地设置颜色。
我的问题:
当 MediatorLiveData 从非活动状态变为活动状态时,因为视图移到了前台updateColor,对于每个更改的源,可能会多次调用该函数。这是不必要的,因为每次调用都已经考虑了所有变量。由于这个函数可能非常复杂并且可能有很多来源,有没有办法避免针对源 LiveDatas 的相同状态多次调用它?
kotlin ×5
android ×4
java ×2
androidx ×1
event-driven ×1
java-8 ×1
java-stream ×1
javascript ×1
kotlin-js ×1
mockito ×1
mockk ×1
sonarlint ×1
unit-testing ×1