Java 如何在Android中调用标准的本机方法?

Java 如何在Android中调用标准的本机方法?,java,android,Java,Android,我是一个Android初学者。我想编写一些java类,利用现有的Android本机方法。作为一个简单的例子,我尝试从FloatMath类中公开floor方法。但是,这会强制关闭应用程序。我复制了下面的代码。它非常简单,目标是v1.6。那么我可以问一下我是否有明显的遗漏?我需要导入任何特殊的库或编译器吗 public class MainActivity extends Activity { public static native float floor(float value);

我是一个Android初学者。我想编写一些java类,利用现有的Android本机方法。作为一个简单的例子,我尝试从FloatMath类中公开floor方法。但是,这会强制关闭应用程序。我复制了下面的代码。它非常简单,目标是v1.6。那么我可以问一下我是否有明显的遗漏?我需要导入任何特殊的库或编译器吗

public class MainActivity extends Activity {

    public static native float floor(float value);  

    float inputFloat = (float) 2.3;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        float outputFloat = floor(inputFloat);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

尝试添加字母
f

float inputFloat = (float) 2.3f;

尝试添加字母
f

float inputFloat = (float) 2.3f;

你不能用这种方式做你想做的事

在JNI(Java本机接口)中,本机方法通过名称链接到特定类

在您的情况下,您需要定义一个本机库,例如
libfoo.so
,它有一个名为
Java\u com\u example\u app\u main activity\u floor
(com.example.app是包名)的导出函数。然后通过
System.loadLibrary(“foo”)
加载库,然后该方法才可用

从其他本机库调用函数的一种方法(除了对应Java类上的Java反射之外)是从C/C++加载库并包装其函数(通过
dlopen
dlsym
等)

如果不知道你想做什么,我就不能说得更具体了


在这里阅读更多关于JNI和本机开发的信息:(有点过时,但JNI部分仍然适用)

你不能用这种方式做你想做的事情

在JNI(Java本机接口)中,本机方法通过名称链接到特定类

在您的情况下,您需要定义一个本机库,例如
libfoo.so
,它有一个名为
Java\u com\u example\u app\u main activity\u floor
(com.example.app是包名)的导出函数。然后通过
System.loadLibrary(“foo”)
加载库,然后该方法才可用

从其他本机库调用函数的一种方法(除了对应Java类上的Java反射之外)是从C/C++加载库并包装其函数(通过
dlopen
dlsym
等)

如果不知道你想做什么,我就不能说得更具体了


在这里阅读更多关于JNI和本机开发的信息:(有点过时,但JNI部分仍然适用)

您喜欢如何处理您的函数?如果您想使用fnc,可以使用
double myvar=Math.floor(arg)为什么不直接调用
Math.floor
?您喜欢如何处理您的函数?如果您想使用fnc,可以使用
double myvar=Math.floor(arg)为什么不直接打电话给
Math.floor
?这与问题完全无关。这与问题完全无关。这正好回答了我的问题。非常感谢。我的最终目标是创建一个修改过的JetLayer类,而不受单例限制。由于构造函数是私有的,所以不像您想象的那么容易。我想我可以A)使用反射在java中的JetLayer上执行直接类操作,或者B)使用相同的底层方法编写自定义JetLayer。根据您的回答,选项B可能不切实际,因为我似乎需要在libmedia.so上执行dlopen-从而打开平台精灵瓶子。OTOH,反射似乎不太吸引人。希望这不是离题,但下面的反射代码似乎可以用于创建多个Jetlayer实例。虽然这感觉像是一个黑客和半。构造函数jetFactory=JetPlayer.class.getDeclaredConstructor();jetFactory.setAccessible(true);JetLayer multiJet=jetFactory.newInstance();没有理由认为这不起作用,但请记住,这显然意味着它是单例的,所以如果您使用多个后端存储,您可能会打破后端存储中的并发性假设。这正好回答了我的问题。非常感谢。我的最终目标是创建一个修改过的JetLayer类,而不受单例限制。由于构造函数是私有的,所以不像您想象的那么容易。我想我可以A)使用反射在java中的JetLayer上执行直接类操作,或者B)使用相同的底层方法编写自定义JetLayer。根据您的回答,选项B可能不切实际,因为我似乎需要在libmedia.so上执行dlopen-从而打开平台精灵瓶子。OTOH,反射似乎不太吸引人。希望这不是离题,但下面的反射代码似乎可以用于创建多个Jetlayer实例。虽然这感觉像是一个黑客和半。构造函数jetFactory=JetPlayer.class.getDeclaredConstructor();jetFactory.setAccessible(true);JetLayer multiJet=jetFactory.newInstance();没有理由认为这不起作用,但请记住,这显然意味着它是一个单例,因此,如果您使用多个后端存储,您可能会打破后端存储中的并发性假设。