英文:
Error: Could not activate JNI Handle - WorkManager implementation in Xamarin
问题
我一直在尝试在.NET中使用Xamarin实现WorkManager (https://developer.android.com/topic/libraries/architecture/workmanager/),以迁移旧代码,其中我们使用了jobscheduler。在启动应用程序时,我收到了一个错误消息:"Error: Could not activate JNI Handle of type MyWorker1",但似乎无法弄清楚为什么我的实现出了问题。
我的基本实现:
using Android.App;
using Android.Content;
using AndroidX.Work;
using System;
using MyTooling.Services;
using MyTooling.ViewModels.Base;
namespace MyTooling.Droid.Workers
{
public abstract class BackgroundWorkerBase : Worker
{
protected MyService1 MyService;
protected WorkerParameters WorkerParameters { get; }
protected BackgroundWorkerBase(Context context, WorkerParameters workerParameters) : base(context, workerParameters)
{
if (!Xamarin.Forms.Forms.IsInitialized)
Xamarin.Forms.Forms.Init(Application.Context, null);
if (!ViewModelLocator.IsRegistered)
ViewModelLocator.RegisterDependencies(Helpers.Settings.UseMocks);
MyService = ViewModelLocator.Resolve<MyService1>();
WorkerParameters = workerParameters;
}
public override Result DoWork()
{
try
{
var success = TryBackgroundWork();
if (!success || AnyWorkLeft())
return Result.InvokeRetry();
else
return Result.InvokeSuccess();
}
catch (Exception ex)
{
Log.LogError(ex);
return Result.InvokeFailure();
}
}
protected abstract bool AnyWorkLeft();
protected abstract bool TryBackgroundWork();
}
}
JNI错误引用的类:
using Android.Content;
using AndroidX.Work;
namespace MyTooling.Droid.Workers
{
public class MyWorker1 : BackgroundWorkerBase
{
public MyWorker1(Context context, WorkerParameters workerParameters) : base(context, workerParameters)
{
}
protected override bool AnyWorkLeft()
{
return MyService.AnyWork1Left();
}
protected override bool TryBackgroundWork()
{
return MyService.TryDoWork1();
}
}
}
希望这能帮助你解决问题。
英文:
I've been trying to implement the WorkManager (https://developer.android.com/topic/libraries/architecture/workmanager/) in .NET using Xamarin (porting old code where we used jobscheduler). On booting up the app, I get an "Error: Could not activate JNI Handle of type MyWorker1", and can't seem to figure out why my implementation is broken.
My base implementation:
using Android.App;
using Android.Content;
using AndroidX.Work;
using System;
using MyTooling.Services;
using MyTooling.ViewModels.Base;
namespace MyTooling.Droid.Workers
{
public abstract class BackgroundWorkerBase : Worker
{
protected MyService1 MyService;
protected WorkerParameters WorkerParameters { get; }
protected BackgroundWorkerBase(Context context, WorkerParameters workerParameters) : base(context, workerParameters)
{
if (!Xamarin.Forms.Forms.IsInitialized)
Xamarin.Forms.Forms.Init(Application.Context, null);
if (!ViewModelLocator.IsRegistered)
ViewModelLocator.RegisterDependencies(Helpers.Settings.UseMocks);
MyService = ViewModelLocator.Resolve<MyService1>();
WorkerParameters = workerParameters;
}
public override Result DoWork()
{
try
{
var success = TryBackgroundWork();
if (!success || AnyWorkLeft())
return Result.InvokeRetry();
else
return Result.InvokeSuccess();
}
catch (Exception ex)
{
Log.LogError(ex);
return Result.InvokeFailure();
}
}
protected abstract bool AnyWorkLeft();
protected abstract bool TryBackgroundWork();
}
}
The class that the JNI error is referring to:
using Android.Content;
using AndroidX.Work;
namespace MyTooling.Droid.Workers
{
public class MyWorker1: BackgroundWorkerBase
{
public MyWorker1(Context context, WorkerParameters workerParameters) : base(context, workerParameters)
{
}
protected override bool AnyWorkLeft()
{
return MyService.AnyWork1Left();
}
protected override bool TryBackgroundWork()
{
return MyService.TryDoWork1();
}
}
}
答案1
得分: 2
我找到了答案。 Proguard/R8 搞乱了 JNI 链接,因此添加一个自定义的 Proguard 配置文件(https://learn.microsoft.com/en-us/xamarin/android/deploy-test/release-prep/proguard?tabs=windows#customizing-proguard)只包含以下行:
-keep class androidx.** {*;}
-keep class android.arch.** {*;}
解决了我的问题!原来我们指望默认配置来完成我们需要的工作,但它没有更新以处理 androidx(我不确定第二行是否需要,但对我们的用途不会有害)。
英文:
I figured out the answer. Proguard/R8 was messing up the JNI linking, so adding a custom proguard configuration file (https://learn.microsoft.com/en-us/xamarin/android/deploy-test/release-prep/proguard?tabs=windows#customizing-proguard) consisting only of the following lines:
-keep class androidx.** {*;}
-keep class android.arch.** {*;}
fixed my issue! Turns out we were counting on the default config to do what we needed, and it hadn't been updated to deal with androidx (I am not sure that the second line there is needed, but it won't hurt for our uses)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论