Reputation: 431
I'm trying to save a mutableList into mediaStore, however I'm getting this error:
java.lang.IllegalArgumentException: Type not supported: interface java.util.List
at com.alclabs.waltv.MainActivity.saveOnDataStore(MainActivity.kt:133)
at com.alclabs.waltv.MainActivity.access$saveOnDataStore(MainActivity.kt:20)
at com.alclabs.waltv.MainActivity$saveChannelsLocalStorage$1.invokeSuspend(MainActivity.kt:90)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8893)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@7c5ee8a, Dispatchers.Main.immediate]
This is my code from the MainActivity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var dataStore: DataStore<Preferences>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
dataStore = createDataStore(name = "settings")
CoroutineScope(Dispatchers.IO).launch {
var state = loadChannels("https://myapi.com/channels")
withContext(Dispatchers.Main) {
binding.txtStatus.text = state
}
}
}
private fun loadChannels(url: String): String {
//connect to url
var document = Jsoup.connect(url).get()
var channelsList = mutableListOf<String>()
//get channels url
var elements = document.select("ul.channels li")
for (element in elements) {
val channel = element.text()
channelsList.add(channel)
}
//get logos
var imagesList = mutableListOf<String>()
var elements2 = document.select("ul.images li")
for (element in elements2) {
val image = element.text()
imagesList.add(image)
}
//create final list of channels
var tvChannelsList = mutableListOf<TvChannel>()
channelsList.forEachIndexed { index, element ->
var ch = TvChannel(channelsList.get(index), imagesList.get(index))
tvChannelsList.add(ch)
}
//print channels..
/*
for(e in tvChannelsList){
println(e.channel_url+ " - " + e.channel_logo)
}
*/
saveChannelsLocalStorage(tvChannelsList)
return "channels loaded!"
}
private fun saveChannelsLocalStorage(listOfChannels: MutableList<TvChannel>) {
lifecycleScope.launch {
saveOnDataStore("channels_list", listOfChannels)
}
}
private suspend fun saveOnDataStore(key: String, value: MutableList<TvChannel>) {
val immutableList: List<TvChannel> = value.toList()
val dataStoreKey = preferencesKey<List<TvChannel>>(key)
dataStore.edit { settings ->
settings[dataStoreKey] = immutableList
}
}
}
Basically I create two mutable lists then I'm creating a final mutableList of objects of type TvChannel:
@Parcelize
data class TvChannel(
val channel_url: String,
val channel_logo: String,
) : Parcelable
I'm using mediaStore version: 1.0.0-alpha01
implementation("androidx.datastore:datastore-preferences:1.0.0-alpha01")
The problem is in this method:
private suspend fun saveOnDataStore(key: String, value: MutableList<TvChannel>) {
val immutableList: List<TvChannel> = value.toList()
val dataStoreKey = preferencesKey<List<TvChannel>>(key)
dataStore.edit { settings ->
settings[dataStoreKey] = immutableList
}
}
Here, basically I'm converting the mutableList to an immutableList, however this doesn't work.
If you want to test my code guys, here is the Jsoup library to make the web scraping:
implementation("org.jsoup:jsoup:1.11.3")
Upvotes: 0
Views: 66
Reputation: 131
Shared preferences is more for key-value pairs, user preference and configurations.
For saving more complex data structures, consider using a local database and ROOM:
https://developer.android.com/training/data-storage/room
Upvotes: 0
Reputation: 95626
Looks like the datastore implementation for preferences does not support List
. I wasn't able to find any documentation on what data types are supported, but since this is supposed to be a replacement for SharedPreferences
I looked at what data types are supported by SharedPreferences
. Basically only single primitive types (no arrays) and Set<String>
are supported by SharedPreferences
. If you want to store more complex data in a datastore, you should use the Protobuf implementation instead of the preferences implementation.
Upvotes: 0