Android Architecture Problem with activity reference - Stack Overflow

admin2025-05-01  1

I have an Android application with lots of NFC and GPS functionality. I need to verify the location of a user with either gps or the scan of a NFC tag.

I created a use case to handle NFC but I would like to not have a reference to my activity in this class. Problem for me is that I need the activity to

  • start the NFC foreground dispatch
  • stop the NFC foreground dispatch

The use case should have a start() function to start the NFC foreground dispatch. It should automatically stop the foreground dispatch after a scan (which needs the activity)

I thought about a class in between my activity and my NFC use case that holds the activity. I call this the InBetweenClass.

class InBetweenClass(val activity: AppCompatActivity) {

private var nfcAdapter: NfcAdapter = NfcAdapter.getDefaultAdapter(activity)

fun startNfc() {
    val intent = Intent(activity, activity.javaClass)
    intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
    val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE)
    } else {
        PendingIntent.getActivity(activity, 0, intent, 0)
    }
    nfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null)
}

fun stopNfc() {
    try {
        nfcAdapter.disableForegroundDispatch(activity)
    } catch (ex: Exception) {
        // tbd   
    }
}

}

Question: I now could handover a reference of the InBetweenClass to my NFC use case. But is this really better than having the activity in my use case? As I hold a reference to the InBetweenClass and this class holds the activity, it seems to me more or less the same as having the activity right in my NFC use case.

What pattern is best to decouple my use case from my activity? My app is a single activity app.

I have an Android application with lots of NFC and GPS functionality. I need to verify the location of a user with either gps or the scan of a NFC tag.

I created a use case to handle NFC but I would like to not have a reference to my activity in this class. Problem for me is that I need the activity to

  • start the NFC foreground dispatch
  • stop the NFC foreground dispatch

The use case should have a start() function to start the NFC foreground dispatch. It should automatically stop the foreground dispatch after a scan (which needs the activity)

I thought about a class in between my activity and my NFC use case that holds the activity. I call this the InBetweenClass.

class InBetweenClass(val activity: AppCompatActivity) {

private var nfcAdapter: NfcAdapter = NfcAdapter.getDefaultAdapter(activity)

fun startNfc() {
    val intent = Intent(activity, activity.javaClass)
    intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
    val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE)
    } else {
        PendingIntent.getActivity(activity, 0, intent, 0)
    }
    nfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null)
}

fun stopNfc() {
    try {
        nfcAdapter.disableForegroundDispatch(activity)
    } catch (ex: Exception) {
        // tbd   
    }
}

}

Question: I now could handover a reference of the InBetweenClass to my NFC use case. But is this really better than having the activity in my use case? As I hold a reference to the InBetweenClass and this class holds the activity, it seems to me more or less the same as having the activity right in my NFC use case.

What pattern is best to decouple my use case from my activity? My app is a single activity app.

Share Improve this question edited Jan 2 at 17:38 Emanuel asked Jan 2 at 16:48 EmanuelEmanuel 92310 silver badges32 bronze badges 3
  • Can you explain more clearly what you're trying to do? Code might help here. – Gabe Sechan Commented Jan 2 at 17:20
  • Rather than pass the Activity in the constructor, pass it in the startNfc parameters. – Gabe Sechan Commented Jan 2 at 17:45
  • You could use the newer and better NFC API of enableReaderMode instead of enableForegroundDispatch, while this still an Activity reference to enable in theory I think people have got the callback method to work in a separate class with no Activity reference. This is better than enableForegroundDispatch which requires you to override the Activities onNewIntent method. – Andrew Commented Jan 2 at 18:49
Add a comment  | 

2 Answers 2

Reset to default 0

Maybe change the signature from:

class InBetweenClass(val activity: AppCompatActivity)

to:

abstract class BaseNfcActivity : AppCompatActivity() /*, NfcAdapter.ReaderCallback */

and also:

class MainActivity : BaseNfcActivity()

Then you have your InBetweenClass, without having to pass anything.

First of all, your activity also shouldn't interact with UseCase. Any business logic should pass through the ViewModel.

For now, let's find a solution to your question:

You can pass an activity as a param of your fun. In this case you won't keep reference anywhere.

Another way is to pass lambda as a param of fun and just invoke this lambda in the ViewModel, Usecase whatever. In this case, your activity reference will be only in activity class. Sometimes it looks not very elegant but at least you keep your UI and domain layers clear. And this is the only one approach for KMP projects.

转载请注明原文地址:http://www.anycun.com/QandA/1746106470a91760.html