Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android studio 編譯C生成.so文件

android studio 編譯C生成.so文件

編輯:關於Android編程

一、前言

前段時間有個同事離職了,用C編譯的.SO文件需要更改,結果C文件是他寫的,無賴啊,自己又是一個小白,不會啊,所以自己又好好鑽研了一天,不會,看什麼都難啊,痛苦啊,網上找了好多,才找到的,而且感覺都不怎麼詳細,步驟說的不是很清楚,所以自己整理了一下,誰便記錄一下,好了,廢話不多說,開始正題。

二、編譯過程

1、編譯環境的搭建

正所謂:“工欲善其事必先利其器”嘛,所以先把改准備工具准備一下,因為是在studio下編譯的,所以啊,什麼studio、什麼sdk、什麼jdk,這些都自己去弄吧,這裡說一下ndk這個編譯C文件工具怎麼下載安裝;

下載鏈接:https://developer.android.com/ndk/downloads/index.html(一般需要翻牆,至於原因嘛,你懂得)進去之後下載自己相對應的ndk平台版本;

下載完了之後直接是一個zip的壓縮包,解壓即可;

然後如下圖所示的配置ndk:

\

 

然後你會在local.properties文件中看到:

\

 

不要急,還沒有完,ndk環境搭建還有最後一步,在gradle.properties的文件末尾加上android.useDeprecatedNdk=true這段代碼,文字看不懂吧直接上圖:

\

好了,到此處環境就搭建完畢了。

2、java代碼和C代碼的編寫步驟及過程

首先新建一個java類JNIUtils.java

 

public class JNIUtils {
    static {
        System.loadLibrary("huazict");
    }

    //java調C中的方法都需要用native聲明且方法名必須和c的方法名一樣
    public native String getString();
}

 

 

然後如下圖所示重新Make Project一下工程:

\

 

會在工程目錄E:\work\MyApplication\stujni\build\intermediates\classes\debug\com\huazi\stujni\jni中看到自己編譯後的class文件JNIUtils.class如下圖所示:

\

 

其次就是生成.h文件了

在studio打開Terminal命令行工具,打開步驟是View->Tool Windows->Terminal (或直接按Alt+F12),如下圖所示:

\

 

然後在命令行中先進入到工程的main目錄下

輸入命令:javah -d jni -classpath 自己編譯後的class文件的絕對路徑

例如:javah -d jni -classpath E:\work\MyApplication\stujni\build\intermediates\classes\debug com.huazi.stujni.jni.JNIUtils(注意debug後的空格)

\

 

看到上圖,圖中命令行中是直接進入到了工程的main目錄下(在哪個目錄下運行就會在哪個目錄下自動生成jni文件夾),按回車之後就會在main目錄下生成jni文件夾,同時生成.h文件,如下圖:

\

 

這個文件.h文件不需要做任何修改,默認即可。

現在我們來寫一個test的C文件huazict.c同.h文件一樣放到jni文件夾下,代碼如下:

 

#include "com_huazi_stujni_jni_JNIUtils.h"
/**
 * 上邊的引用標簽一定是.h的文件名家後綴,方法名一定要和.h文件中的方法名稱一樣
 */
JNIEXPORT jstring JNICALL Java_com_huazi_stujni_jni_JNIUtils_getString
        (JNIEnv *env, jobject obj) {
    return (*env)->NewStringUTF(env, "這是我測試的jni");
}

 

 

如圖所示:

\
 

最後在構建文件中的默認配置中加上:

 

 //ndk編譯生成.so文件
        ndk {
            moduleName "huazict"         //生成的so名字
            abiFilters "armeabi", "armeabi-v7a", "x86"  //輸出指定三種abi體系結構下的so庫。
        }

 

 

如圖:

\
 

到這裡,通過jni調C就完成了,現在我們來測試一下,寫個TextView顯示一下調用的C:

 

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView)findViewById(R.id.tv);

        tv.setText(new JNIUtils().getString());
    }
}

 

 

看效果,直接上圖:

\

 

ok,沒問題,可以調用,其實也沒有想象中的那麼難,是吧!

三、調用編譯過的.so庫

上邊編譯完成了,有人會問:我要的是編譯後的.so庫,別人用的時候直接拿來用就可以了,那編譯後的.so庫在哪呢?不要著急請看下圖:

\

 

根據這個路徑就可以找到指定輸出的三種體系結構下的.so庫文件,然後把.so文件復制出來,如下圖所示的放到相應的文件夾下就ok了:

\

再次運行,結果還是一樣的,跟上邊貼的那張圖的顯示效果是是一樣的,同樣能調用到,代碼我就不上傳了,都在上邊貼上去了,而且也上傳不了,公司的所有文件都是加密的,想上傳都上傳不了。

到這裡,整個jni的調用過程就結束了,包括調用jni需要的環境以及調用的過程,最後.so文件的導出,都在上邊了,如果上邊的jni調用過程有什麼問題,歡迎留言,謝謝。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved