【问题标题】:get application name from NDK从 NDK 获取应用程序名称
【发布时间】:2012-04-02 19:49:52
【问题描述】:

我需要像这样从本机端获取我的 android 应用程序的名称:

 android.content.context context=(android.content.context) this;//current activiy
 Resources appR =context.getResources();
 String packageName=context.getPackageName();
 int id=appR.getIdentifier("app_name","string",packageName );
 CharSequence txt = appR.getText(id);

我的本​​机代码是这样的:

  jstring Java_com_AnalyticToolC_AnalyticToolActivity_JNISendData(JNIEnv* env,jobject entryObject,jobject contxt)
 {

   char *realAppName;
 realAppName=(char *)malloc(16 * 1024);
 jclass android_content_Context =(*env)->GetObjectClass(env, contxt);
    jmethodID midGetPackageName = (*env)->GetMethodID(env, android_content_Context, "getPackageName", "()Ljava/lang/String");
 jstring packageName=(*env)->CallObjectMethod(env, contxt, midGetPackageName);
jmethodID midGetResources = (*env)->GetMethodID(env, android_content_Context, "getResources", "()L");
    jobject jResource=(*env)->CallObjectMethod(env, context, midGetResources);

   jclass resource_Class=(*env)->GetObjectClass(env, jResource);
   jmethodID midGetIdentifier = (*env)->GetMethodID(env, resource_Class, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String)I");
   jstring app_name=(*env)->NewStringUTF(env,"app_name");
   jstring TypeName=(*env)->NewStringUTF(env,"string");
   int id=(*env)->CallObjectMethod(env, jResource, midGetIdentifier,app_name,TypeName,packageName);

  jmethodID midGetAppName = (*env)->GetMethodID(env, resource_Class,"getText","(I)Ljava/lang/String");
  jstring appName=(*env)->CallObjectMethod(env, jResource, midGetAppName,id);   

  realAppName=(*env)->GetStringUTFChars(env, appName, NULL);
}

我只是将活动从 java 代码传递给我的本地方法。

我没有机会在 java 类中编写这段代码,然后从我的 NDK 应用程序中调用它 我正在尝试将上下文对象作为作业对象传递给我的本机代码,但它总是崩溃。 有人知道吗?

【问题讨论】:

标签: android android-ndk


【解决方案1】:

C 中反映的 Java 访问是丑陋的,丑陋的,丑陋的,就像您所展示的那样。将应用名称作为额外的字符串参数传递。

编辑:好的,你想要反射,你会得到反射。

您的本机方法属于类AnalyticToolActivity。作为一个非静态类方法,它在每次调用时都有一个this 指针。与 C++ 和 Java 方法不同,此指针作为第二个参数显式传递。该方法有两个强制参数 - JNIEnv *jobject。第二个对应Java对象的this指针。

因此,如果您的 AnalyticToolActivityActivity 的子类 - 很可能 - entryObject 参数是 Activity 的实例,这意味着它是 Context 的实例。所以去掉第三个参数(contxt),你的JNI代码就可以这样了:

jclass android_content_Context =(*env)->GetObjectClass(env, entryObject);
//or use FindClass

jmethodID midGetPackageName = (*env)->GetMethodID(env,
    android_content_Context,
    "getPackageName",
    "()Ljava/lang/String;");

jstring packageName=(*env)->CallObjectMethod(env, entryObject, midGetPackageName); 

等等。

【讨论】:

  • 我知道它很难看,很难看,但情况就是这样,我还需要访问 SharedPreferences 对象,如果有人可以提供帮助,我真的很感激
  • 措辞表明您的本机方法属于您的活动类。活动上下文的子类。如果您的本机方法是静态的,请将其删除;然后将 this 指针 (AKA entryObject) 视为上下文引用。
  • 对不起,我没听明白,但我的本地方法不是静态方法,你的意思是 (jobject entryObject) 应该是我的传递对象“来自 java 端的活动”
  • 谢谢,我解决了你必须输入的方法签名问题;如果您的方法将返回对象而不是原始类型对象,它应该看起来像 "()Ljava/lang/String;"
  • 绝妙的答案...从那段中学到的东西比从整本书中学到的更多
【解决方案2】:

为什么需要从 NDK 执行此操作?也许对我们来说,帮助您调试传递上下文对象的问题会更有用,然后您可以将应用名称作为字符串传递。

【讨论】:

  • 我这样做是因为我有一个 C 库,它将被其他本机应用程序使用,所以我需要在我的 C 库中使用应用程序名称,无论如何我会用我的本机代码更新问题。
猜你喜欢
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
相关资源
最近更新 更多