如何将C ++集成到Android Java应用程序中?

时间:2014-08-05 23:59:36

标签: java android c++

我想使用C ++在后台运行服务,它将处理图像。但是我无法在C ++中编写整个应用程序,因为它是一个协作项目,我将如何在C ++中创建一个Android服务,然后从java编写的应用程序中调用/运行它?

1 个答案:

答案 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);
    }
}
相关问题