FreddicMatters
FreddicMatters

Reputation: 431

Can't save a mutableList into android mediaStore

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

Answers (2)

keyboard_user
keyboard_user

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

David Wasser
David Wasser

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

Related Questions