我想使用C ++在后台运行服务,它将处理图像。但是我无法在C ++中编写整个应用程序,因为它是一个协作项目,我将如何在C ++中创建一个Android服务,然后从java编写的应用程序中调用/运行它?
答案 0 :(得分:1)
您应该查看Java Native Interface (JNI)
请记住,我没有尝试使用Android或Android API做任何事情,但这是我使用JNI处理运行嵌入式Java 8版本的Linux ARM芯片的经验。
您需要交叉编译要用于android os的任何C ++文件。当您将JAR打包为在Andrioid设备上运行时,您需要包含可以静态链接到的已编译二进制文件。您可以使用本机方法从Java调用C ++方法,并且可以在C ++程序中存储指向JVM的指针,并对来自C ++的方法进行回调。
如果你使用像maven这样的东西打包你的项目,有些插件会自动为你做这件事。
这是我们用于编译嵌入式Linux操作系统的配置。 (你必须为自己的目的修改它)
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>1.0-alpha-7</version>
<extensions>true</extensions>
<configuration>
<javahOS>linux</javahOS>
<jdkIncludePath>${embeddedJDKIncludePath}</jdkIncludePath>
</configuration>
<executions>
<execution>
<id>javah</id>
<phase>generate-sources</phase>
<configuration>
<!-- trigger javah execution -->
<javahClassNames>
<javahClassName> LIST CLASS NAMES </javahClassName>
</javahClassNames>
<javahOS>linux</javahOS
<javahOutputDirectory>${project.build.directory}/include</javahOutputDirectory>
<javahProvider>default</javahProvider>
<javahVerbose>true</javahVerbose>
</configuration>
<goals>
<goal>javah</goal>
</goals>
</execution>
</executions>
</plugin>
您当然希望将LIST CLASS NAMES
替换为您要为其生成C ++ JNI绑定的实际类列表。
然后你可以像这样声明类:
class RunService extends JNIWrapper {
public native boolean runService();
//More methods if you want. You can pass pretty much anything back
//and forth between native code.
}
您还需要编写加载到C ++文件中的JNIWrapper类。这个JNIWrapper文件看起来像这样。
static
{
try
{
if( !libraryLoaded )
{
// create temporary file
jniLibrary = File.createTempFile([name of some temporary file]);
// flag for delete on exit
jniLibrary.deleteOnExit();
byte [] buffer = new byte[1024];
int readBytes;
InputStream is = JNIWrapper.class.getResourceAsStream([link to directory inside your compiled JAR where your C++ binary has been placed]);
OutputStream os = new FileOutputStream(jniLibrary);
try
{
while((readBytes = is.read(buffer)) != -1 )
{
os.write(buffer, 0, readBytes);
}
}
finally
{
os.close();
is.close();
}
libraryLoaded = true;
}
System.load(jniLibrary.getAbsolutePath());
}
catch( Exception ex )
{
ex.printStackTrace();
System.exit(1);
}
}