I have a multimodule project with the following structure:
app:
core:
|- common
feature:
|-games:
| |-general:
| |-meaninggame:
|
|-settings
etc.
The game needs a list of proverbs whcihb ultimately will be downloaded from a backend but for testing purposes will be read from a file. In the module :general I have a class ProverbRepositoryFileImpl:
class ProverbRepositoryFileImpl: ProverbRepository {
override fun getListOfProverbs(number: Int): List<Proverb> {
val proverbList = proverbs()
return if(number == 0 || proverbList.size<number){
proverbList
}
else{
val start = (0 .. proverbList.size-number).random()
proverbList.subList(start,start+number)
}
}
override fun getListOfProverbsContaining(key: String, number: Int): List<Proverb> {
val proverbList = proverbs().filter{it.part_1.contains(key) || it.part_2.contains(key)}
return if(number == 0 || proverbList.size<number){
proverbList
}
else{
val start = (0 .. proverbList.size-number).random()
proverbList.subList(start,start+number)
}
}
//Helper function to read json from file
private fun proverbs(): List<Proverb> {
val serverResponse = getJsonResponse("proverbs.json")
val proverbList = Json.decodeFromString<Array<Proverb>>(serverResponse)
return proverbList.toList()
}
private fun getJsonResponse(filepath:String):String{
val uri = javaClass.classLoader?.getResource(filepath)
val file = uri?.path?.let { File(it) }
file?.let{return String(file.readBytes())}?:let{return ""}
}
}
The last two functions read a list of json formatted proverbs from a file. The file is placed in the resources directory of the general module. When I run the tests all test passes, so the file is being read. But when I run the app to play the game, a java.io.FileNotFoundException is being thrown.
Where do I have to place the file to have the proverbs read? Or should I use another approach to get the list of proverbs into the game?
I solved the problem by using the following code:
class LoadJsonFromFile(private val context:Context ){
fun loadFile(resourceId:Int): String {
var json: String? = null
try {
val inputStream = context.resources.openRawResource(resourceId)
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
inputStream.close()
json = String(buffer, StandardCharsets.UTF_8)
} catch (e: IOException) {
e.printStackTrace()
}
return json?:""
}
}
The class is injected in the ProverbRepositoryFileImpl class and the helper function is changed as shown below:
class ProverbRepositoryFileImpl(val fileLoader:LoadJsonFromFile): ProverbRepository{
...
//Helper function to read json from file
private fun proverbs(): List<Proverb> {
val serverResponse = fileLoader.loadFile(R.raw.proverbs)
val proverbList = Json.decodeFromString<Array<Proverb>>(serverResponse)
return proverbList.toList()
}
}