Xamarin Forms with WorkManger

Viewed 869

I am trying to use the Xamarin implementation of WorkManager, in the nuget package Xamarin.Android.Arch.Work.Runtime.

The questions is: how to pass "complex" parameters to the worker class?

I have a Xamarin Forms application with DI and others classes, but the job only receives a Java.Lang.Object.

My code:

// Method to Schedule the Job
// See the dataParam? That line throw an exception
// I can manage to pass a simple string or int to the job this way, but not 
// complex classes
public void ScheduleAppJobs(IContainerProvider containerRegistry)
{
       //here the code throw an exception
       var dataParam = new Data.Builder().Put("param", new JobParameter());
        
       var syncWorkerReuest = PeriodicWorkRequest.Builder.From<SyncChecklistWorker>(TimeSpan.FromMinutes(5))
                                                                      .SetInputData(dataParam.Build())
                                                                      .Build(); 
       WorkManager.Instance.Enqueue(syncWorkerReuest);
    }

    //this was my try to create a custom class and populate with my objects
    //But didn't worked
    public class JobParameter : Java.Lang.Object
    {
    }

    //my job implementation
    public class SyncChecklistWorker : Worker
        {
            public SyncChecklistWorker(Context context, WorkerParameters workerParameters) : base(context, workerParameters)
            {
            }
    
            public override Result DoWork()
            {
                if (InputData.KeyValueMap.TryGetValue("param", out Java.Lang.Object @object))
                {
                    var jobParam = (JobParameter)@object;
    
                    // here I would like to get my DI container to resolve services and execute business logic
                    // var diResolver = jobParam.GetDIContainer();
    
                    return Result.InvokeSuccess();
                }
    
                return Result.InvokeRetry();
            }
        }
}

The problem is:

  • The only way to pass input data to a jobs the Data.Builder only accepts Java.Lang.Object. Even trying to approach of having JobParameter : Java.Lang.Object I get the following error when trying to execute the: new Data.Builder().Put("param", new JobParameter()); Error: Java.Lang.IllegalArgumentException: 'Key param has invalid type class crc648d221dddf00bc7fb.JobParameter'
  • On the official Microsoft Docs the FireBase Job Dispatcher nuget is deprecated. So how to work with the new WorkManager one?

FireBase Job Dispatcher Doc: https://docs.microsoft.com/en-us/xamarin/android/platform/firebase-job-dispatcher

Deprecated nuget: https://www.nuget.org/packages/Xamarin.Firebase.JobDispatcher

Any idea of how to solve this?

1 Answers

Work request from Data builder accepts only the premitive types. You can pass the object by serializing to JSON string format and in DoWork() you can deserialize it.

 public void ScheduleAppJobs(IContainerProvider containerRegistry)
 {
    var dataParam = new Data.Builder().PutString("param",serializeToJson(new  
    MyClass())); 

    var syncWorkerReuest = PeriodicWorkRequest.Builder.From<SyncChecklistWorker> 
    (TimeSpan.FromMinutes(5))                                                                  
    .SetInputData(dataParam.Build())
    .Build();  
     WorkManager.Instance.Enqueue(syncWorkerReuest);
   }

   public override Result DoWork()
   {
     var jsonString = InputData.GetString("param");
     var myClassObj = deserializeFromJson(jsonString );
    }
 
    using Newtonsoft.Json;
    public  string serializeToJson(MyClass myClassObj)
     {
        var resultString = JsonConvert.SerializeObject(myClassObj);
        return resultString;
     }

      // Deserialize to single object.
      public  MyClass deserializeFromJson(string jsonString)
      {
        var serializer = new JsonSerializer();
        var resultObject = serializer.Deserialize<MyClass>(jsonString);
      }
Related