jniデバッグ
4856 ワード
12年の時にJNIを書いたことがありますが、あまり忘れていません.今もう一度書き直しましたが、いくつかの問題にぶつかったことに気づきました.書いて記録してください.
最初のステップ
アプリケーションjavaコード
コンパイルするとeclipseコンパイルでもjavaコマンドコンパイルでも構いません
コンパイル後、次のコード構造とディレクトリがあります.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls AndroidManifest.xml classes classes.dex dexedLibs helloWorld.apk res resources.ap_ weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
ステップ2
共有ヘッダファイルを生成するには、成功と失敗に最も重要な関係があります.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -d header -classpath classes -jni com.example.helloworld.AlarmTest weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
このコマンド比較キーjavah-d headerとは、現在のディレクトリの下にこのヘッダファイルを生成することです.-classesを指定するディレクトリは、最初のステップで生成されます.
-jniとは、jniヘッダファイルcomを生成することを意味する.example.helloworldこれはパッケージ名AlarmTestクラス名ですこれらはすべて間違いありません
生成後は次のようになります.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls AndroidManifest.xml classes classes.dex dexedLibs header helloWorld.apk res resources.ap_ weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls header/com_example_helloworld_AlarmTest.h weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
最初はわかりませんでしたが、実行中によくエラーが発生します.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -jni com.example.helloworld error: cannot access com.example.helloworld class file for com.example.helloworld not found javadoc: error - Class com.example.helloworld not found. Error: No classes were specified on the command line. Try -help. weiqifa@weiqifa-inspron-3847:~/workspace/helloWorld/bin$自動生成対応関数:Java_com_example_helloworld_AlarmTest_test
Java_ + パッケージ名(com_example_helloworld)+クラス名(AlarmTest)+インタフェース名(test):このJNI仕様に従って操作する必要があります.
ステップ3
通過するhで作ります.c
私たちを見てください.c私たちはただ必要です.hの中のその関数の名前、.hは参照されず、コンパイルやプリコンパイルにも関与していない
helloworld.c以下:
ステップ4
soファイルの生成
私たちのmkファイルを見てください.
次のsoファイルが生成されます.weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$ ls libhelloWorld.so weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$
ステップ5
検証の実行
直接eclipseでインストールするかadb pushで中に入ってadbを使う場合はsoファイルを手動でインストールして権限を変更します
10-20 03:06:45.241: E/weiqifa(12194): weiqifa hello for JNI 10-20 03:06:45.241: V/ActivityThread(12194): activityCreated r=ActivityRecord{41e7a890 token=android.os.BinderProxy@41e7a060 {com.example.helloworld/com.example.helloworld.AlarmTest}}
質問:
最初はAndroidにいましたmkに書いてあるLOCAL_MODULEが生成したモジュール名は大文字W,helloWorld
でもandroidソースには
中のhelloworldは小文字wで、それから運行はずっとロードに成功していません.後ろの友达が見てくれました.原因を見つけて、油断しましょう.
最初のステップ
アプリケーションjavaコード
package com.example.helloworld;
import java.util.Calendar;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.util.Log;
public class AlarmTest extends Activity
{
AlarmManager aManager;
Calendar currentTime = Calendar.getInstance();
public static final int POWER_OFF_WAKE_UP = 8;//
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("weiqifa", test());
}
public native String test();
static {
try{
Log.i("JNI", "Trying to load libhelloworld.so");
System.loadLibrary("helloWorld");
}catch(UnsatisfiedLinkError ule){
Log.e("JNI", "Warning : could not load the libhelloworld.so");
}
}
}
コンパイルするとeclipseコンパイルでもjavaコマンドコンパイルでも構いません
コンパイル後、次のコード構造とディレクトリがあります.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls AndroidManifest.xml classes classes.dex dexedLibs helloWorld.apk res resources.ap_ weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
ステップ2
共有ヘッダファイルを生成するには、成功と失敗に最も重要な関係があります.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -d header -classpath classes -jni com.example.helloworld.AlarmTest weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
このコマンド比較キーjavah-d headerとは、現在のディレクトリの下にこのヘッダファイルを生成することです.-classesを指定するディレクトリは、最初のステップで生成されます.
-jniとは、jniヘッダファイルcomを生成することを意味する.example.helloworldこれはパッケージ名AlarmTestクラス名ですこれらはすべて間違いありません
生成後は次のようになります.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls AndroidManifest.xml classes classes.dex dexedLibs header helloWorld.apk res resources.ap_ weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls header/com_example_helloworld_AlarmTest.h weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ cat header/com_example_helloworld_AlarmTest.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_helloworld_AlarmTest */
#ifndef _Included_com_example_helloworld_AlarmTest
#define _Included_com_example_helloworld_AlarmTest
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_helloworld_AlarmTest_POWER_OFF_WAKE_UP
#define com_example_helloworld_AlarmTest_POWER_OFF_WAKE_UP 8L
/*
* Class: com_example_helloworld_AlarmTest
* Method: test
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_helloworld_AlarmTest_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
最初はわかりませんでしたが、実行中によくエラーが発生します.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -jni com.example.helloworld error: cannot access com.example.helloworld class file for com.example.helloworld not found javadoc: error - Class com.example.helloworld not found. Error: No classes were specified on the command line. Try -help. weiqifa@weiqifa-inspron-3847:~/workspace/helloWorld/bin$自動生成対応関数:Java_com_example_helloworld_AlarmTest_test
Java_ + パッケージ名(com_example_helloworld)+クラス名(AlarmTest)+インタフェース名(test):このJNI仕様に従って操作する必要があります.
ステップ3
通過するhで作ります.c
私たちを見てください.c私たちはただ必要です.hの中のその関数の名前、.hは参照されず、コンパイルやプリコンパイルにも関与していない
helloworld.c以下:
#include <string.h>
#include <jni.h>
JNIEXPORT jstring JNICALL Java_com_example_helloworld_AlarmTest_test
(JNIEnv *env, jobject thiz)
{
return (*env)->NewStringUTF(env,"weiqifa hello for JNI");
}
ステップ4
soファイルの生成
私たちのmkファイルを見てください.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := helloWorld
LOCAL_SRC_FILES := helloWorld.c
include $(BUILD_SHARED_LIBRARY)
次のsoファイルが生成されます.weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$ ls libhelloWorld.so weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$
ステップ5
検証の実行
直接eclipseでインストールするかadb pushで中に入ってadbを使う場合はsoファイルを手動でインストールして権限を変更します
10-20 03:06:45.241: E/weiqifa(12194): weiqifa hello for JNI 10-20 03:06:45.241: V/ActivityThread(12194): activityCreated r=ActivityRecord{41e7a890 token=android.os.BinderProxy@41e7a060 {com.example.helloworld/com.example.helloworld.AlarmTest}}
質問:
最初はAndroidにいましたmkに書いてあるLOCAL_MODULEが生成したモジュール名は大文字W,helloWorld
LOCAL_MODULE := helloWorld
でもandroidソースには
System.loadLibrary("helloWorld");
中のhelloworldは小文字wで、それから運行はずっとロードに成功していません.後ろの友达が見てくれました.原因を見つけて、油断しましょう.