0

I am building an app that needs to detect certain objects in photos. I first load and keep all the photos I'd like to inspect into my room Database and connect it to my view with a ViewHolder. When the user clicks a button, I want the detection process to begin, and I want to use a jobIntentService for that (As there might be thousands of photos there).

My problem is - how do I access the view holder from within the Service? I need it both to actually get a hold of the files and also so I can update each file's record once detection has been made. I've tried to ask for the activity as one of the attributes, but I am getting this error

Unable to instantiate service tech.levanter.anyvision.services.DetectJobIntentService: java.lang.InstantiationException: java.lang.Class<tech.levanter.anyvision.services.DetectJobIntentService> has no zero argument constructor

Would appreciate any input, thanks

Tsabary
  • 3,119
  • 2
  • 24
  • 66

1 Answers1

1

ViewModels holds particular significance for Activities and Fragments (e.g. they retain data during config changes). So a Service doesn't really need it. Hence you can resolve the issue in one of two ways.

Approach 1:

If your MyViewModel is just a wrapper for accessing LiveData from your Repository class, then you can just use your Repository class inside your Service.

Approach 2:

If your ViewModel is doing more than just wrapping calls to the Repository and you want your Service class to have access to the same logic defined in your ViewModel, then use an intermediate ViewModelContent class. Instead of putting everything in your MyViewModel class, put them in a "ViewModelContent" class. Then use your MyViewModel class as an accessor wrapper around ViewModelContent. Then your Service can instantiate ViewModelContent as you would any other class.

class MyViewModel(application: Application) : AndroidViewModel(application) {
   init{
      viewModelContent = ViewModelContent(...) 
   }
}

Approach 1 will usually be cleaner than Approach 2.

Isai Damier
  • 976
  • 6
  • 8
  • If following this approach doesn't work for you, then include your ViewModel code in your post so we can see what's causing the issue. – Isai Damier Nov 13 '19 at 17:48
  • But for which owner? What value do I put under `of` when initiating the viewHolder like this `ViewModelProviders.of(it).get(AllPhotosViewModel::class.java)`. I use my viewHolder to communicate with the repository which in turn communicates with my database and should change items, based on the operations that run in my service. – Tsabary Nov 13 '19 at 17:56
  • Personally, I would use LocalBroadcastManager to send the intent to the fragment/activity, if we’re still using that fragment then we will pick it up and push it into the current view model (as the viewModel has a life cycle of the fragments lifecycle – Brandon Nov 13 '19 at 17:59
  • @Brandon, thanks, I'll look into that. Can you suggest how to access the the viewModel at all? I need access to it to interact with the repository and the DB, but don't know what to insert inside the `if` part, as it requests and activity or a fragment. Trying different ideas but it accepts nothing so far – Tsabary Nov 13 '19 at 18:10