I have two .aidl files and I need to add them to a project delphi.
IPrinterCallback.aidl
IPrinterService.aidl
// IPrinterService.aidl
package com.xcheng.printerservice;
import com.xcheng.printerservice.IPrinterCallback;
//import java.util.List;
//import java.util.Map;
// Declare any non-default types here with import statements
interface IPrinterService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
...
...
The idea is simply to create a button to click and print anything using these packages.
I read several tutorials and got nothing so far.
In one of them I saw that I needed to generate the equivalent .java files and add them to the project.
/*
* This file is auto-generated. DO NOT MODIFY.
*/
package com.xcheng.printerservice;
//import java.util.List;
//import java.util.Map;
// Declare any non-default types here with import statements
public interface IPrinterService extends android.os.IInterface
{
/** Default implementation for IPrinterService. */
public static class Default implements com.xcheng.printerservice.IPrinterService
{
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
#Override public void upgradePrinter() throws android.os.RemoteException
{
...
...
...
So I generated them using aidl.exe from skd android and put them in a folder inside the project.
But I always get a compilation error when I try to import it in 'uses'.
my code without importing the AIDL
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Os,
Android.ServiceApplication,
FMX.Helpers.Android;
type
TForm1 = class(TForm)
Print: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
end.
MyProject/
|
+-- src/
| |
| +-- com/
| |
| +-- xcheng/
| |
| +-- printerservice/
| |
| +-- IPrinterService.aidl
| +-- IPrinterCallback.aidl
| +-- IPrinterService.java
| +-- IPrinterCallback.java
|
+-- assets/
|
+-- AndroidManifest.xml
+-- MyProject.dproj
...
...
Can anyone help me import and consume these files .aidl or .java in android delphi?
Related
I created 2 random modules I exported "com.alice" package from folder A and require the module in folder B. Then compiled A: javac mod10/A/module-info.java mod10/A/com/alice/Ship.java and tried to compile B javac mod10/B/module-info.java mod10/B/com/alice2/Main.java. And I get this:
error: module not found: com.alice
requires com.alice;
^
1 error
why I get "module not found" error message?
Shouldn't it be the whole point of exporting a module to make it visible to other modules?
In mod10/A/module-info.java
module com.alice {
exports com.alice;
}
Ship.java
package com.alice;
public class Ship {
private String name;
public Ship() {
this.name = "Ship Created";
}
public String getName() {
return this.name;
}
}
In mod10/B/module-info.java
module com.alice2 {
requires com.alice;
}
Main.java
package com.alice2;
import com.alice;
public class Main {
public static void main(String[] args) {
Ship x = new Ship();
System.out.println("Ship made" + x.getName());
}
}
Folder Tree:
mod10 (root)
|_ A
|_ com
|_ alice
|_ Ship.java
|_ module-info.java
|_ B
|_ com
|_ alice2
|_ Main.java
|_ module-info.java
I have a c++ library being linked with JNI to Java classes in an Android Studio project, and I am getting an error when trying to use env->GetFieldID() inside JNIAnalalog.cpp
This is the error I get when trying to load in a double from AnalogConfig.java
07-12 14:30:57.597 14360-14360/com.company.myapplication A/art: art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: JNI NewGlobalRef called with pending exception java.lang.NoSuchFieldError: no "D" field "deadband" in class "[Lcom/automatak/dnp3/AnalogConfig;" or its superclasses
art/runtime/java_vm_ext.cc:470] at java.lang.String java.lang.Runtime.nativeLoad(java.lang.String, java.lang.ClassLoader, java.lang.String) (Runtime.java:-2)
art/runtime/java_vm_ext.cc:470] at java.lang.String java.lang.Runtime.doLoad(java.lang.String, java.lang.ClassLoader) (Runtime.java:1060)
art/runtime/java_vm_ext.cc:470] at void java.lang.Runtime.loadLibrary0(java.lang.ClassLoader, java.lang.String) (Runtime.java:975)
art/runtime/java_vm_ext.cc:470] at void java.lang.System.loadLibrary(java.lang.String) (System.java:1567)
art/runtime/java_vm_ext.cc:470] at void com.company.myapplication.MainActivity.<clinit>() (MainActivity.java:10) // This is where the c++ library is being loaded
I get the error no "D" field "deadband"; however, deadband is defined as a public double inside its java class, as seen below. So I am not sure why it is not considered a "D" field.
If I comment these two lines out and try to use the other env->GetFieldID(), I get a similar error: java.lang.NoSuchFieldError: no "[Lcom/automatak/dnp3/enums/EventAnalogVariation;" field "eventVariation" in class "[Lcom/automatak/dnp3/AnalogConfig;" or its superclasses.
I am not sure if the error is caused only by JNI or if Android Studio is part of the problem
This file set up inside my /app/src/main/ for the relevant files
.
|-- cpp
| `-- // Other libraries are located here
|
|-- dotnet
|
|-- java
| |-- com
| | |-- automatak
| | | `-- dnp3
| | | |-- AnalogConfig.java
| | | |-- EventConfig.java
| | | |-- enums
| | | | |-- EventAnalogVariation.java
| | | | `-- PointClass.java
| | | |-- impl
| | | `-- mock
| | `-- company
| | `-- myapplication
| | `-- MainActivity.java
| |-- cpp
| | |-- adapters
| | |-- JNI.cpp
| | `-- JNI.h
| | `-- jni
| | |-- JNIAnalogConfig.cpp
| | `-- JNIAnalogConfig.h
This is all of the relevant code inside the files
JNIAnalogConfig.cpp
#include "JNIAnalogConfig.h"
namespace jni
{
namespace cache
{
bool AnalogConfig::init(JNIEnv* env)
{
auto clazzTemp = env->FindClass("[Lcom/automatak/dnp3/AnalogConfig;");
this->clazz = (jclass) env->NewGlobalRef(clazzTemp);
env->DeleteLocalRef(clazzTemp);
this->deadbandField = env->GetFieldID(this->clazz, "deadband", "D");
if(!this->deadbandField) return false; // Crashes here
this->eventVariationField = env->GetFieldID(this->clazz, "eventVariation", "[Lcom/automatak/dnp3/enums/EventAnalogVariation;");
if(!this->eventVariationField) return false;
this->clazzField = env->GetFieldID(this->clazz, "clazz", "[Lcom/automatak/dnp3/enums/PointClass;");
if(!this->clazzField) return false;
return true;
}
}
}
JNIAnalog.Config.h
#ifndef OPENDNP3JAVA_JNIANALOGCONFIG_H
#define OPENDNP3JAVA_JNIANALOGCONFIG_H
#include <jni.h>
#include "../adapters/LocalRef.h"
namespace jni
{
struct JCache;
namespace cache
{
class AnalogConfig
{
friend struct jni::JCache;
bool init(JNIEnv* env);
void cleanup(JNIEnv* env);
public:
// field getter methods
jdouble getdeadband(JNIEnv* env, jobject instance);
LocalRef<jobject> geteventVariation(JNIEnv* env, jobject instance);
LocalRef<jobject> getstaticVariation(JNIEnv* env, jobject instance);
private:
jclass clazz = nullptr;
// field ids
jfieldID deadbandField = nullptr;
jfieldID eventVariationField = nullptr;
jfieldID clazzField = nullptr;
};
}
}
#endif
AnaglogConfig.java
import com.automatak.dnp3.enums.EventAnalogVariation;
public class AnalogConfig extends EventConfig {
public AnalogConfig(int index) {
super(index);
}
public double deadband = 0;
public EventAnalogVariation eventVariation = EventAnalogVariation.Group32Var1;
}
EventConfig.java
import com.automatak.dnp3.enums.PointClass;
public class EventConfig {
public EventConfig(int vIndex) {
this.vIndex = vIndex;
this.clazz = PointClass.Class1;
}
public int vIndex;
public PointClass clazz;
}
Any help is appreciated, thank you!
Let's say I have a main class App that loads all jars in the sub-directory plugins using a URLClassLoader:
public class App(){
public static void main(String[] args){
for(File f : new File("plugins").listFiles()){
URL[] urls = { new URL("jar:file:" + "plugins/" + f.getName() + ".jar" + "!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls);
Class<?> clazz = cl.loadClass(f.getName().toLowerCase()+"."+f.getName());
cl.close();
Plugin p = ((Plugin) clazz.newInstance());
}
}
}
All those jars contain a class that implements an interface Plugin.
+-- Main.jar
| +-- App.class
| +-- Plugin.class
|
+-- Plugins/
| +-- PluginTest.jar
| +-- plugintest
| +-- PluginTest.class
| +-- Two.class
That's all working fine if I write my code just in the PluginTest class. But as soon as I try to access Two from PluginTest, I'm getting a big error:
Exception in thread "Thread-4" java.lang.NoClassDefFoundError: plugintest/Two
[...]
How should I load the the class correctly? Need help! Thanks.
Do not close your classloader.
Remove cl.close();statement.
In my grammar i have an include rule as follow :
Script:
includes+=(Include)* assignments+=(Assignment)* clock=Clock? tests+=Test*
;
Include:
'INCLUDE' importURI=STRING
;
what I want to do is to include files same as the "main" file.
I'm working with an interpreter that handels the .mydsl file.
/* Main exec methode */
def dispatch void exec(Script s) {
s.includes.forEach[ i | i.exec]
s.assignments.forEach[a | a.exec]
s.clock.exec
s.tests.forEach[t|t.exec]
}
/* include methode */
def dispatch void exec(Include i) {
System.out.println( i.importURI + " included")
}
Xtext imports are not includes. Xtext does not support includes at all. All that Xtext supports are Cross References. You can use namespace based or import uri based global scoping to determine how elements from other files can be found. assume you really want to follow the includes files in your interpreter
Script:
includes+=(Include)*
;
Include:
'INCLUDE' includedScript=[Script|STRING]
;
And Name Provider
public class MyDslQNP extends DefaultDeclarativeQualifiedNameProvider {
QualifiedName qualifiedName(Script script) {
return QualifiedName.create(script.eResource().getURI().trimFileExtension().lastSegment(), script.eResource().getURI().fileExtension());
}
}
then you can follow the reference in your interpreter
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
override bindIQualifiedNameProvider() {
MyDslQNP
}
}
My main folder is ABC inside it is 2 folders named classes and src, inside src is 2 folders named objectFile and testFile, inside objectFile is ABC.java while inside testFile is TestABC.java.(inside classes is the same but .class instead) now ABC contains
package objectFile;
public class ABC
private int something;
while TestABC.java contains
package testFile;
import objectFile.ABC;
public class TestABC
error says TestABC.java:2: error: package objectFile does not exist
import objectFile.ABC;
Are you specifying the sourcepath? This tells the compiler where to find the classes that it needs to import.
javac -sourcepath src -d classes src\testFile\TestABC.java
Note that this compiles not just TestABC.java, but ABC.java as well (because of your import statement).
You can then put the classes into an archive using the jar command:
jar cfe myJavaArchive.jar testFile/TestABC -C classes .
This will create a new jar with the filename myJavaArchive.jar and entrypoint testFile/TestABC made from all the files in the classes directory.
Because it is the entry point, TestABC must have a main method, e.g.
package testFile;
import objectFile.ABC;
public class TestABC {
public static void main(String[] args) {
ABC abc1 = new ABC(1);
ABC abc2 = new ABC(2);
System.out.println("abc1.i is " + abc1.getI());
System.out.println("abc2.i is " + abc2.getI());
}
}
and
package objectFile;
public class ABC {
private int i;
public ABC(int i) {
this.i = i;
}
public int getI() {
return i;
}
}
Then you can execute the code using the java -jar command:
java -jar myJavaArchive.jar