I have a singleton class like FileLog that I want to create a file in one of its methods and need a Context to do it. My problem is that FileLog class was placed in another module and I don't have access to the app module context. can you tell me how can I access the context using Hilt or other ways?.
Edited -------------------------->>>>><<<<<<--------------------------
this is my class that is a singleton. if I pass it a context I will face a memory leak. I need context just in one method and I don't want to pass a context to that method as a parameter. if I access a class that extends Application() and has a static context in it, I can use it in the FileLog class method.
open class FileLog private constructor(context: Context) {
private lateinit var streamWriter: OutputStreamWriter
private var dateFormat: SimpleDateFormat? = null
private var currentFile: File? = null
private var networkFile: File? = null
private var tonlibFile: File? = null
private var initied = false
private var context: Context = context
companion object {
lateinit var INSTANCE: FileLog
@Synchronized
fun getInstance(context: Context): FileLog {
if (!Companion::INSTANCE.isInitialized) {
INSTANCE = FileLog(context)
}
return INSTANCE
}
}
fun initFileLog(context: Context) {
Log.e("FileLog", "create file")
if (initied) {
return
}
dateFormat = SimpleDateFormat("dd_MM_yyyy_HH_mm_ss", Locale.US)
try {
val sdCard: File = context.getExternalFilesDir(null)
?: return
val dir = File(sdCard.absolutePath "/logs")
dir.mkdirs()
currentFile =
File(dir, dateFormat?.format(System.currentTimeMillis()).toString() ".txt")
} catch (e: Exception) {
e.printStackTrace()
}
}
CodePudding user response:
Do your logger actually needs Context
? No, it needs a File
of external files dir.
fun initFileLog(sdCard: File) {
Log.e("FileLog", "create file")
if (initied) {
return
}
dateFormat = SimpleDateFormat("dd_MM_yyyy_HH_mm_ss", Locale.US)
try {
val dir = File(sdCard.absolutePath "/logs")
...
}
}}
And you can provide such File
from the app module.
As a rule of thumb, you should avoid Android dependencies in your modules, that enables them to be tested in simpler environment.
CodePudding user response:
I think you can also use object class as it holds only one instance
object FileLos{
private lateinit var streamWriter: OutputStreamWriter
private var dateFormat: SimpleDateFormat? = null
private var currentFile: File? = null
private var networkFile: File? = null
private var tonlibFile: File? = null
private var initied = false
fun initFileLog(context: Context) {
Log.e("FileLog", "create file")
if (initied) {
return
}
dateFormat = SimpleDateFormat("dd_MM_yyyy_HH_mm_ss", Locale.US)
try {
val sdCard: File = context.getExternalFilesDir(null)
?: return
val dir = File(sdCard.absolutePath "/logs")
dir.mkdirs()
currentFile =
File(dir, dateFormat?.format(System.currentTimeMillis()).toString() ".txt")
} catch (e: Exception) {
e.printStackTrace()
}
}}
CodePudding user response:
Instead of passing the context to the method, you can expose the app context in the App class:
class App : Application() {
companion object {
val context: App
get() = contextReference.get()!! as App
}
}
and use it like this:
App.context.getExternalFilesDir(null)