第八節(jié)(c\c++調(diào)用java代碼)

先看個(gè)命令:javap(獲取方法的簽名啊研,其實(shí)不用這個(gè)命令也行,自己應(yīng)該也看的出來(lái)方法的簽名整葡,只是介紹個(gè)工具)
javap命令操作的是class文件

調(diào)用java非靜態(tài)方法

以這段代碼為例:

package com.example.huozhenpeng.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText("");
    }
    public String getJavaMethod(int max)
    {
        return "helloworld";
    }
}
image.png
image.png
hhh:myapplication huozhenpeng$ javap -s -p MainActivity.class 
Compiled from "MainActivity.java"
public class com.example.huozhenpeng.myapplication.MainActivity extends android.support.v7.app.AppCompatActivity {
  public com.example.huozhenpeng.myapplication.MainActivity();
    descriptor: ()V

  protected void onCreate(android.os.Bundle);
    descriptor: (Landroid/os/Bundle;)V

  public java.lang.String getJavaMethod(int);
    descriptor: (I)Ljava/lang/String;

  static {};
    descriptor: ()V
}

示例

package com.example.huozhenpeng.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getJavaMethod();
    }

    public native void getJavaMethod();
    public String addMethod(int max)
    {
        return max+"helloworld";
    }
}

extern "C"
JNIEXPORT void JNICALL
Java_com_example_huozhenpeng_myapplication_MainActivity_getJavaMethod(JNIEnv *env,
                                                                      jobject instance) {

    jclass  jcs=env->GetObjectClass(instance);
    jmethodID  jmd=env->GetMethodID(jcs,"addMethod","(I)Ljava/lang/String;");//L表示的是對(duì)象類(lèi)型
    jobject  job=env->CallObjectMethod(instance,jmd,200);
    jstring  js= (jstring) job;
    const char *value=env->GetStringUTFChars(js,NULL);
    printf("%s\d",value);


}

找不到輸出c++的地方虏缸,直接debug查看吧:


image.png

調(diào)用java靜態(tài)方法

這樣一個(gè)場(chǎng)景:在java中生成uuid(c語(yǔ)言生成uuid比較復(fù)雜),在c中調(diào)用java中的方法獲取uuid蚁堤,生成一個(gè)文件uuid.txt,并向文件寫(xiě)入helloworld醉者。
試了很多次,androidstudio始終fopen文件失敗披诗,找不出原因撬即,操作文件的功能先放下。

private native void generateFileByC();

    private static String getUUID()
    {
        return UUID.randomUUID().toString();
    }
extern "C"
JNIEXPORT void JNICALL
Java_com_example_huozhenpeng_myapplication_MainActivity_generateFileByC(JNIEnv *env,
                                                                        jobject instance) {
    jclass  jcl=env->GetObjectClass(instance);
    jmethodID  jmd=env->GetStaticMethodID(jcl,"getUUID","()Ljava/lang/String;");
    jstring jsg= (jstring) env->CallStaticObjectMethod(jcl, jmd);
    const char *p =env->GetStringUTFChars(jsg,NULL);
    char s[100];
    sprintf(s,"/storage/emulated/0/%s.txt",p);
    printf("%s\n",s);

}
image.png

jni操作java構(gòu)造方法

例如:c語(yǔ)言中沒(méi)有Date對(duì)象呈队,如果我們要獲取當(dāng)前時(shí)間就比較麻煩剥槐,所以直接在jni中獲取java的Date然后調(diào)用Date的getTime()方法。

TextView textView= (TextView) findViewById(R.id.sample_text);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
Date date=new Date(testJniCustructor());
textView.setText("當(dāng)前時(shí)間:"+simpleDateFormat.format(date));
private native long testJniCustructor();
extern "C"
JNIEXPORT jlong JNICALL
Java_com_example_huozhenpeng_myapplication_MainActivity_testJniCustructor(JNIEnv *env,
                                                                          jobject instance) {
    jclass  jcs=env->FindClass("java/util/Date");

    jmethodID  jmd=env->GetMethodID(jcs,"<init>","()V");//構(gòu)造函數(shù)的方法名都是<init>

    //實(shí)例化Date
    jobject  job=env->NewObject(jcs,jmd);


    //得到getTime的methodId
    jmethodID  jme=env->GetMethodID(jcs,"getTime","()J");//long的簽名是J不是L

    jlong jl=env->CallLongMethod(job,jme);

    return jl;

}

測(cè)試結(jié)果:

image.png

操作String

關(guān)于String亂碼

在java層定義String宪摧,傳遞給jni
 setString("好好學(xué)習(xí)");
 private native void setString(String str);
extern "C"
JNIEXPORT void JNICALL
Java_com_example_huozhenpeng_myapplication_MainActivity_setString(JNIEnv *env, jobject instance,
                                                                  jstring str_) {
    const char *str = env->GetStringUTFChars(str_, NULL);



    env->ReleaseStringUTFChars(str_, str);
}
image.png

沒(méi)有演示出來(lái)亂碼粒竖,尷尬了。有亂碼的百度下啊几于,基本上windows的話(huà)用的是WideCharToMultiByte蕊苗,其他的貌似需要借助三方。

在jni定義字符串沿彭,傳給java
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_huozhenpeng_myapplication_MainActivity_getStringFromC(JNIEnv *env,
                                                                       jobject instance) {
    const char *p="哈哈哈哈";
    return env->NewStringUTF(p);
}
 private native String getStringFromC();

 TextView textView= (TextView) findViewById(R.id.sample_text);
 textView.setText(getStringFromC());

測(cè)試結(jié)果:

image.png

沒(méi)有亂碼朽砰,尷尬。
如果有亂碼的話(huà)可以借助java層的String類(lèi)帶charset的構(gòu)造方法實(shí)現(xiàn)。

看下GetStringUTFChars的第三個(gè)參數(shù)的作用:
當(dāng)從JNI函數(shù)GetStringUTFChars函數(shù)中返回得到字符串B時(shí)瞧柔,如果B是原始字符串java.lang.String的一份拷貝漆弄,則isCopy 被賦值為JNI_TRUE。如果B是和原始字符串指向的是JVM中的同一份數(shù)據(jù)造锅,則isCopy 被賦值為JNI_FALSE撼唾。 當(dāng)isCopy 為JNI_FALSE時(shí),本地代碼絕不能修改字符串的內(nèi)容备绽,否則JVM中的原始字符串也會(huì)被修改券坞,這會(huì)打破Java語(yǔ)言中字符串不可變的規(guī)則

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肺素,隨后出現(xiàn)的幾起案子恨锚,更是在濱河造成了極大的恐慌,老刑警劉巖倍靡,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猴伶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡塌西,警方通過(guò)查閱死者的電腦和手機(jī)他挎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捡需,“玉大人办桨,你說(shuō)我怎么就攤上這事≌净裕” “怎么了呢撞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)饰剥。 經(jīng)常有香客問(wèn)我殊霞,道長(zhǎng),這世上最難降的妖魔是什么汰蓉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任绷蹲,我火速辦了婚禮,結(jié)果婚禮上顾孽,老公的妹妹穿的比我還像新娘祝钢。我一直安慰自己,他們只是感情好若厚,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布太颤。 她就那樣靜靜地躺著,像睡著了一般盹沈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天乞封,我揣著相機(jī)與錄音做裙,去河邊找鬼。 笑死肃晚,一個(gè)胖子當(dāng)著我的面吹牛锚贱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播关串,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼拧廊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了晋修?” 一聲冷哼從身側(cè)響起吧碾,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎墓卦,沒(méi)想到半個(gè)月后倦春,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡落剪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年睁本,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忠怖。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呢堰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凡泣,到底是詐尸還是另有隱情枉疼,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布问麸,位于F島的核電站往衷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏严卖。R本人自食惡果不足惜席舍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哮笆。 院中可真熱鬧来颤,春花似錦、人聲如沸稠肘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)项阴。三九已至滑黔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背略荡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工庵佣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汛兜。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓巴粪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親粥谬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肛根,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容