绑定Xamarin中的JobIntentService类

时间:2018-03-23 16:15:34

标签: android xamarin

我有一个在Android中使用JobIntentService的java类(包名:import android.support.v4.app.JobIntentService;。 这个类用在我在Xamarin项目中绑定的.aar文件中。

我创建了一个应用程序,它将.aar文件用于那里可用的某些方法。

建筑操作正常。

但问题发生在我运行应用程序时,它会抛出一个

Java.Lang.NoClassDefFoundError has been thrown
Failed resolution of : Lcom/<package_name_of_class>/MyService$Background

我检查了References目录,以查看该课程是否存在,而且该课程确实存在......

我添加了属性

<attr path="/api/package[@name='com.<package_name_of_class>']/class[@name='MyService.Background']" name="extends">java.lang.Object</attr>

Metadata.xml目录下的Transforms文件中绑定该服务。

我知道关于该课程的连接存在一些问题,但我真的不知道要解决它......

为了解决这个问题,我该怎么办?

编辑2

例如,在我的.aar文件中,我有这个类:

public class MyService{

/**
 * Class which handles Foreground execution behaviour.
 *
 *
 * */
public static class Foreground extends IntentService{
    public Foreground(){super("MyService.Foreground");}

    @Override
    public void onCreate() {
        super.onCreate();
        MyService.onCreate(this.getApplicationContext());
    }

    /**
     * This method is invoked on the worker thread with a request to process.
     * Only one Intent is processed at a time, but the processing happens on a
     * worker thread that runs independently from other application logic.
     * So, if this code takes a long time, it will hold up other requests to
     * the same IntentService, but it will not hold up anything else.
     * When all requests have been handled, the IntentService stops itself,
     * so you should not call {@link #stopSelf}.
     *
     * @param intent The value passed to {@link
     *               Context#startService(Intent)}.
     *               This may be null if the service is being restarted after
     *               its process has gone away; see
     *               {@link Service#onStartCommand}
     *               for details.
     */
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        MyService.onHandleIntent(this.getApplicationContext(), intent);
    }
}

/**
 * Class which handles Background execution behaviour for android Oreo.
 *
 * */
public static class Background extends JobIntentService{
    private static final String TAG = "MyService.Background";
    protected static final int JOB_ID = 8888;


    /**
     * Convenience method for enqueuing work in to this service.
     */
    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, MyService.Background.class, MyService.Background.JOB_ID, work);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        MyService.onCreate(this.getApplicationContext());
    }

    /**
     * Called serially for each work dispatched to and processed by the service.  This
     * method is called on a background thread, so you can do long blocking operations
     * here.  Upon returning, that work will be considered complete and either the next
     * pending work dispatched here or the overall service destroyed now that it has
     * nothing else to do.
     * <p>
     * <p>Be aware that when running as a job, you are limited by the maximum job execution
     * time and any single or total sequential items of work that exceeds that limit will
     * cause the service to be stopped while in progress and later restarted with the
     * last unfinished work.  (There is currently no limit on execution duration when
     * running as a pre-O plain Service.)</p>
     *
     * @param intent The intent describing the work to now be processed.
     */
    @Override
    protected void onHandleWork(@NonNull Intent intent) {
        MyService.onHandleIntent(this.getApplicationContext(), intent);
    }
}

 public static void onCreate(Context mApplicationContext) {
    Apps.init(mApplicationContext);
}

protected static void onHandleIntent(Context mApplicationContext, Intent intent) {
    String action = intent.getAction();
    Bundle extras = intent.getExtras();

    // etc
}
}

在我的Transforms文件夹中,我添加了该行:

<attr path="/api/package[@name='com.android.internal.service']/class[@name='MyService.Background']" name="extends">mono.android.app.Service</attr>

请注意,此类是JobIntentService,也许它可能是问题的根源......

但我也用那条线测试过:

<attr path="/api/package[@name='com.android.internal.service']/class[@name='MyService.Background']" name="extends">java.lang.Object</attr>

问题仍在运行时继续

编辑3

当我构建项目时,api.xml文件生成这些行:

<class abstract="false" deprecated="not deprecated" 

extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="MyService" static="false" visibility="public">
<constructor deprecated="not deprecated" final="false" name="MyService" static="false" type="com.android.internal.service.MyService" visibility="public">
</constructor>
<method abstract="false" deprecated="not deprecated" final="false" name="onCreate" native="false" return="void" static="true" synchronized="false" visibility="public">
<parameter name="p0" type="android.content.Context">
</parameter>
</method>
<method abstract="false" deprecated="not deprecated" final="false" name="onHandleIntent" native="false" return="void" static="true" synchronized="false" visibility="protected">
<parameter name="p0" type="android.content.Context">
</parameter>
<parameter name="p1" type="android.content.Intent">
</parameter>
</method>
</class>
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="MyService.1" static="true" visibility="">
<implements name="java.lang.Runnable" name-generic-aware="java.lang.Runnable">
</implements>
<method abstract="false" deprecated="not deprecated" final="false" name="run" native="false" return="void" static="false" synchronized="false" visibility="public">
</method>
</class>
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="MyService.2" static="true" visibility="">
<implements name="java.lang.Runnable" name-generic-aware="java.lang.Runnable">
</implements>
<method abstract="false" deprecated="not deprecated" final="false" name="run" native="false" return="void" static="false" synchronized="false" visibility="public">
</method>
</class>
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="MyService.3" static="true" visibility="">
<implements name="java.lang.Runnable" name-generic-aware="java.lang.Runnable">
</implements>
<method abstract="false" deprecated="not deprecated" final="false" name="run" native="false" return="void" static="false" synchronized="false" visibility="public">
</method>
</class>
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="MyService.4" static="true" visibility="">
<implements name="java.lang.Runnable" name-generic-aware="java.lang.Runnable">
</implements>
<method abstract="false" deprecated="not deprecated" final="false" name="run" native="false" return="void" static="false" synchronized="false" visibility="public">
</method>
</class>
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="MyService.5" static="true" visibility=""/>

<class abstract="false" deprecated="not deprecated" extends="android.support.v4.app.JobIntentService" extends-generic-aware="android.support.v4.app.JobIntentService" final="false" name="MyService.Background" static="true" visibility="public">
<constructor deprecated="not deprecated" final="false" name="MyService.Background" static="false" type="com.android.internal.service.MyService.Background" visibility="public">
</constructor>
<method abstract="false" deprecated="not deprecated" final="false" name="enqueueWork" native="false" return="void" static="true" synchronized="false" visibility="public">
<parameter name="p0" type="android.content.Context">
</parameter>
<parameter name="p1" type="android.content.Intent">
</parameter>
</method>
<method abstract="false" deprecated="not deprecated" final="false" name="onHandleWork" native="false" return="void" static="false" synchronized="false" visibility="protected">
<parameter name="p0" type="android.content.Intent">
</parameter>
</method>
<field deprecated="not deprecated" final="true" name="JOB_ID" static="true" transient="false" type="int" type-generic-aware="int" value="8888" visibility="protected" volatile="false">
</field>
</class>
<class abstract="false" deprecated="not deprecated" extends="android.app.IntentService" extends-generic-aware="android.app.IntentService" final="false" name="MyService.Foreground" static="true" visibility="public">
<constructor deprecated="not deprecated" final="false" name="MyService.Foreground" static="false" type="com.android.internal.service.MyService.Foreground" visibility="public">
</constructor>
<method abstract="false" deprecated="not deprecated" final="false" name="onHandleIntent" native="false" return="void" static="false" synchronized="false" visibility="protected">
<parameter name="p0" type="android.content.Intent">
</parameter>
</method>
</class>

编辑3

enter image description here

2 个答案:

答案 0 :(得分:1)

根据您的描述和代码,您将创建一个依赖于Android.Support.V4库的类。如果缺少依赖关系,绑定库将自动删除该类。

因此,您需要做的是将Xamarin.Android.Support.v4 nuget包添加到绑定库中,它将正常工作:

enter image description here

在这种情况下,无需编辑metadata.xml文件。

答案 1 :(得分:0)

以下是如何在转换目录下声明元数据文件的示例。

<metadata>
    <!--
  This sample removes the class: android.support.v4.content.AsyncTaskLoader.LoadTask:
  <remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />

  This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
  <remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
  -->
    <remove-node path="/api/package[starts-with(@name, 'com.actionbarsherlock.internal')]" />


    <!-- Canonicalize the Java package names -->
    <attr path="/api/package[@name='com.actionbarsherlock']" name="managedName">Xamarin.ActionbarSherlockBinding</attr>
    <attr path="/api/package[@name='com.actionbarsherlock.widget']" name="managedName">Xamarin.ActionbarSherlockBinding.Widget</attr>
    <attr path="/api/package[@name='com.actionbarsherlock.app']" name="managedName">Xamarin.ActionbarSherlockBinding.App</attr>
    <attr path="/api/package[@name='com.actionbarsherlock.view']" name="managedName">Xamarin.ActionbarSherlockBinding.Views</attr>
</metadata>

有关完整的项目样本,请参阅以下链接, https://github.com/xamarin/monodroid-samples/blob/master/ActionBarSherlock/ActionBarSherlock/Transforms/Metadata.xml