Home > Software design >  Using application context in another module
Using application context in another module

Time:04-20

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)
  • Related