【问题标题】:Calling c program from different Android project从不同的Android项目调用c程序
【发布时间】:2017-09-15 12:06:47
【问题描述】:

我使用的是 Android Studio 版本 - 2.1.2。我在 Android 中创建了一个项目 - MyNdk。本项目使用 c 程序。 c程序有一个功能 获取国家/地区()。该函数在文件 torento.c 中创建。 功能是这样的-

Java_com_myndk_MainActivity_getCountry(JNIEnv *env, jobject instance) **{**

   // TODO
   //return (*env)->NewStringUTF(env, returnValue);

   return (*env)->NewStringUTF(env, "Canada");

**}**

在 java 文件中,我使用此代码加载库 System.loadLibrary("torento")。 libtorento.so 已创建 成功在所有设备的 jni 文件夹下。到目前为止没问题,我可以毫无错误地调用c程序。

现在我创建了第二个项目 - HelloAndroidJni。这个项目也使用了c程序。我想使用 libtorento.so 中的 getCountry()。 本项目有c程序paris.c,创建于jni文件夹下。对于这个项目,库是 libparis.so。 现在,我创建了一个文件夹 jniLibs,在该文件夹下我从第一个项目中为所有设备复制了 libtorento.so。然后我使用以下内容加载了库 java文件中的代码。

static
{
    System.loadLibrary("torento");
    System.loadLibrary("paris");

}

libtorento.so 在 HelloAndroidJni 项目中加载成功。我检查了 .apk 文件。 libtorento.so 存在于 .apk 文件中。

我的问题是如何在 HelloAndroidJni 项目中调用 getCountry() 。我搜索了很多,到处都有教程/示例 其中 c 程序是从定义它的同一个 java 项目中调用的。 请帮帮我。

在 Android Studio(2.1.2) 中,系统生成 jni 文件夹和 c 文件。没有创建头文件。

【问题讨论】:

标签: java android c android-ndk .so


【解决方案1】:

在第二个项目中,您应该创建一个新的 Java 类 com.myndk.MainActivity(我知道 t 与新项目的主要活动不在同一个 Java 包中)。您可以从 myNdk 项目中复制 MainActivity.java 文件,或者直接创建一个新文件。唯一的要求是该类已经定义了本地方法 get country()。

现在您可以在新应用中使用此方法。

【讨论】:

    【解决方案2】:

    按照您的指示,我在 HelloAndroidJni 中制作了这个。我做对了吗?我的课如下

    包 com.dsc.bandhan.helloandroidjni;

    @SuppressWarnings("JniMissingFunction") 公共类 MainActivity 扩展 AppCompatActivity {

    TextView txtName;
    
    
    static
    {
        System.loadLibrary("torento");
        System.loadLibrary("paris");
    
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        txtName=(TextView)findViewById(R.id.txtName);
    
        txtName.setText(getCountry());
    
    
    }
    
    
    public native String getCountry();
    

    }

    它不工作。它显示以下错误 java.lang.UnsatisfiedLinkError:找不到本机方法:com.dsc.bandhan.helloandroidjni.MainActivity.getCountry:()Ljava/lang/String;

    【讨论】:

    • 我明确地写了这个,但不知何故丢失了:本机方法 getCountry 应该在包 com.myndk 的 MainActivity 类中定义,而不是在包 com.dsc.bandhan.helloandroidjni 中。
    • 我已经在 com.myndk 包的 MainActivity 中定义了 getCountry()。它在那里工作正常,并且还为所有设备成功生成了 libtorento.so 文件。在我的第二个项目中 System.loadLibrary("torento") 加载没有错误,但我无法调用 getCountry()。
    • 没错。第二个项目看不到第一个项目的 MainActivity 类。这就是为什么你不能调用它的 getCountry()。你可以让第一个项目的 MainActivity 类对第二个项目可用,也可以作弊,只为第二个项目提供它的一小部分接口。
    • 亚历克斯,非常感谢。这是工作。我在第一个项目中创建了一个类,其中包括本机函数和方法,来自我称为本机函数的方法。然后我制作了jar文件。在第二个项目中,我包含了该 jar 文件并调用了该类的方法。早些时候我想,我可以使用一些限定符直接从 .so 文件中调用本机函数。不能那样做吗?这里如果我有 10 个原生函数,我必须在类中定义 10 个方法。我的工作方向是否正确?
    • JAR 是一个完全合理的解决方案。实际上,使用 AAR 会更好:另一种存档形式,可以包含已编译的 Java 类和本机代码(以 .so 文件的形式)。 Android Studio(它的 gradle 插件)可以为库获取 AAR 文件,并将 .so 文件正确放入生成的 APK 文件中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2020-08-23
    相关资源
    最近更新 更多