i'm having a well known problem in android which is generating random numbers. the problem is that i need to generate 20 random numbers between 1 and 905 every time a screen is loaded. and if i use kotlin random it keeps generating the same sequence even if i'm closing and reopen the app. and java random and secure random generates different sequence only if i'm closing and reopening the app. but i want to have different sequences even if i dont close the app and open it again.
i know it has been asked before but my problem is that i tried every solution and its the same results.
i would appreciate the help if anyone knows what the hell is wrong.
here are the solutions i used:
1.
val randomIndex: List<Int> = List(20){
java.util.Random().nextInt(905) + 1
}
val randomIndex: MutableSet<Int> = remember{ mutableSetOf() }
while (randomIndex.size < 20){
randomIndex.add(java.util.Random().nextInt(905) + 1)
}
val randomIndex: List<Int> = (0..905).toList.shuffled(Random).subList(0,20)
i'm using jetpack compose and kotlin so ignore all the mutable state and remembers. also where ever you see Random i used all java Random, SecureRandom and kotlin Random and the problem i discussed persists.
i also tried initializing Random out of loop on the second code i put here and still it does the same thing.
EDIT:
thought i mentioned these here aswell. i'm using kolin 1.6.10 and my compile sdk for android is 33. i'm also trying the app on 2 different phones with android 8 and 11.
EDIT2:
#Tenfout04 suggested to put my indexes outside of my composable so this is what i did inside of my viewmodel:
var pokemonIndex: List<Int> = mutableStateListOf()
init {
pokemonIndex = List(20){
java.util.Random().nextInt(905)+1
}
}
and in my composable:
val viewModel: PokemonGameViewModel = hiltViewModel()
val randomIndex = viewModel.pokemonIndex
another thing i tried in my viewmodel is:
val pokemonIndex: MutableState<List<Int>>
get() = mutableStateOf(
List(20){
java.util.Random().nextInt(905)+1
}
)
results are the same :(
I took a Codelab Lunch-tray App it had no Tests so I tried to create these tests to practice. I tried to create testcases for it based on another codelab Codelab Cupcake
The way these 2 projects differ is that on the second codelab(Lunch-tray) the "Next" button is in uppercase.
Which I can not figure out how to write a test to make it pass.
val myNextButton = composeTestRule.activity.getString(R.string.btn_next).uppercase()
composeTestRule.onNodeWithText(myNextButton).performClick()
navController.assertCurrentRouteName(LixoPlayScreen.SideDishScreen.name)
This seems to work, but on mouse over activity I see this message
Avoid calling often as it can involve synchronization and can be slow.
In the onNodeWithText method you can set the ignoreCase to true.
Something like:
composeTestRule.onNodeWithText(
text = composeTestRule.activity.getString(R.string.next),
ignoreCase = true)
.performClick()
In the codelab, to use the onNodeWithStringId method just change:
fun <A : ComponentActivity> AndroidComposeTestRule<ActivityScenarioRule<A>, A>.onNodeWithStringId(
#StringRes id: Int
): SemanticsNodeInteraction = onNodeWithText(activity.getString(id),ignoreCase = true)
I am using the sunflow app example (https://github.com/android/sunflower) as a basis to learn Hilt, Room and many other nice concepts of android coding.
In the PlantDetailViewModel class there is this line:
val plantId: String = savedStateHandle.get<String>(PLANT_ID_SAVED_STATE_KEY)!!.
But I cannot see nowhere in the entire project where PLANT_ID_SAVED_STATE_KEY is set.
am I missing something?
Thanks
It is set, to the string plantId in the PlantDetailViewModel class (at the bottom - line 55) using :-
companion object {
private const val PLANT_ID_SAVED_STATE_KEY = "plantId"
}
Anyone wonder this ? Splitting SPACE (" ") in kotlin is not working, i tried with different regex codes but is not working at all.
Tried with this :
value.split("\\s")[0];
value.split("\\s+")[0];
value.split("\\s++")[0];
Then i came up with solution -> Create java constant class which contains this function and returns string array to your kotlin class.
Is there any other solution for this problem where we can directly achieve this thing?
Solution : As #Edson Menegatti said :
KOTLIN Specific : WORKING
values.split("\\s".toRegex())[0]
Many people suggested this solution : NOT WORKING
values.split(" ")[0]
But in my case it's not working.
Here's an issue between the Java and Kotlin implementation of String.split.
While the Java implementation does accept a regex string, the Kotlin one does not. For it to work, you need to provide an actual Regex object.
To do so, you would update your code as follows:
value.split("\\s".toRegex())[0]
Also, as #Thomas suggested, you can just use the regular space character to split your string with:
value.split(" ")[0]
Final point, if you're only using the first element of the split list, you might want to consider using first() instead of [0] - for better readability - and setting the limit parameter to 2 - for better performance.
You need to use :
.toRegex()
fun main(args: Array<String>) {
val str = "Kotlin com"
val separate1 = str.split("\\s".toRegex())[0]
println(separate1) // ------------------> Kotlin
}
OR
You can also use .split(" ")[0] to achieve result. Like
fun main(args: Array<String>) {
val str = "Kotlin com"
val separate1 = str.split(" ")[0]
println(separate1) // ----------> Kotlin
}
String#split (actually CharSequence#split) can take either a regular expression, or just a string which is interpreted literally. So:
value.split(" ")[0]
does what you want.
If you're only using the first element, it's more efficient to also pass limit = 2. Or, even better, use substringBefore.
Kotlin tries to resolve some issues that Java's String library has. For instance, Kotlin tries to be more explicit.
As a result, the split method takes a normal String and does not use it as a regex internally:
"hello world".split("\\s")[0] //no match
"hello world".split(" ")[0] // => "hello"
To explicitly use the overloaded split function that actually takes a regex, the toRegex() extension can be used (inline fun String.toRegex(): Regex (source)):
"hello world".split("\\s".toRegex())[0]// => "hello"
The following shows another example of Kotlin resolving the confusing String::replaceAll method:
Taken from a KotlinConf presentation of Svetlana Isakova, co-author of “Kotlin in Action”
Single delimiter
val splittedStringList = "123.345-80A".split(".")
println(splittedStringList[0])
Several delimiters
println("123.345-80A".split(".", "-"))
Using regex
println("123.345-80A".split("\\.|-".toRegex()))
Try Kotlin Online
Simply use value.split("\s".toRegex())
1.Splits and iterates all items
value.split("\\s".toRegex()).forEach { item ->
//use item
}
2.Spits and use first item
value.split("\\s".toRegex()).first()
3.Spits and use last item
value.split("\\s".toRegex()).last()
I am trying to develop a nativescript plugin to perform some functionality with the Azure SDK. The docs for the SDK show below:
So I have added the following function to my plugin:
MobileServiceUser.newUser = function (userId, client) {
var userObject = com.microsoft.windowsazure.mobileservices.authentication.MobileServiceUser(userId); // causing the error
client.setCurrentUser(userObject);
};
UserId is a string.
However, the top line throws the error:
JS: Error: Trying to link invalid 'this' to a Java object
I have a full repo showing the minimal implimentation to create this issue on Github.
I would be really grateful of any suggestions how to fix this.
This answer is a little late but I recently ran into this issue myself. Hopefully this answer helps someone in the future!
The error is a bit plain but if you take a look at the code source, you'll see that it's actually telling you that you cannot link a variable to the Object/Class itself as a reference:
MobileServiceUser.newUser = function (userId, client) {
var userObject = com.microsoft.windowsazure.mobileservices.authentication.MobileServiceUser(userId);
};
When you want to instantiate a class, you need to use the keyword new to signify this action. Without new listed before the class constructor call, the program just sees that you're making a direct link between userObject and the class itself. This should fix your problem:
var userObject = new com.microsoft.windowsazure.mobileservices.authentication.MobileServiceUser(userId);
Cheers
~Px