我有一个在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
答案 0 :(得分:1)
根据您的描述和代码,您将创建一个依赖于Android.Support.V4
库的类。如果缺少依赖关系,绑定库将自动删除该类。
因此,您需要做的是将Xamarin.Android.Support.v4
nuget包添加到绑定库中,它将正常工作:
在这种情况下,无需编辑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