Android Studio用cmake編譯SDL2

先說(shuō)SDL(Simple DirectMedia Layer)的作用吧葛闷,SDL是套跨平臺(tái)的多媒體庫(kù)媳危,代碼是用c語(yǔ)言寫的鹅搪,在Android應(yīng)用開(kāi)發(fā)上多是和FFmpeg合作來(lái)開(kāi)發(fā)我們常用的視音頻播放器恤左。關(guān)于FFmpeg移植到Android可參加博客:FFmpeg(3.3.2)移植Android平臺(tái)Android Studio通過(guò)cmake創(chuàng)建FFmpeg項(xiàng)目就可以了既荚。先上一張F(tuán)Fmpeg+SDL2實(shí)現(xiàn)的音頻播放器效果(后面開(kāi)發(fā)完了也會(huì)開(kāi)源出來(lái)的稚失,可做網(wǎng)絡(luò)音樂(lè)或FM等SDK的使用)

SDL2和FFmpeg開(kāi)發(fā)的音頻播放器

我在上一篇博客中(Android編譯SDL2和demo展示(2.0.5))已經(jīng)實(shí)現(xiàn)了把SDL2移植到Android平臺(tái)上,但是是在eclipse+NDK下面編譯的恰聘,隨著Android Studio的興起句各,現(xiàn)在開(kāi)發(fā)Android都不用eclipse了,所以就打算用AS再編譯一次晴叨。
在編譯的過(guò)程中發(fā)現(xiàn)AS已經(jīng)不支持低版本的NDK了凿宾,只好用最新版本的NDK(NDK國(guó)內(nèi)下載地址)這里我用的是13b版本的,但是新的NDK已經(jīng)改變了編譯clang來(lái)編譯不再是gcc了兼蕊,直接移植源碼發(fā)現(xiàn)編譯到了和OpenGL相關(guān)的庫(kù)時(shí)就報(bào)錯(cuò)了初厚,找不到相應(yīng)的引用,嘗試了各種方法都誤解孙技,最終想到了通過(guò)移植SDL2.so庫(kù)和.c源文件的方式來(lái)移植产禾,這種方式完全不影響我們添加自己的C代碼,也算一種比較好的解決辦法了牵啦。
一亚情、用AS創(chuàng)建C/C++項(xiàng)目,這里需要注意蕾久,由于Java和c語(yǔ)言的調(diào)用是個(gè)包名類名方法名相關(guān)的势似,所以當(dāng)我們?cè)赟DL中編譯SDL2.so庫(kù)時(shí)使用了怎樣的包名結(jié)構(gòu)和類結(jié)構(gòu)拌夏,這里也需要一樣的結(jié)構(gòu)才行僧著,不然不能調(diào)用,新項(xiàng)目的包名可以不一樣障簿,新建包的包名和SDL2.so庫(kù)里面的一樣就可以了盹愚。這里就用默認(rèn)的包名和類名開(kāi)演示。
1站故、用AS創(chuàng)建C/C++項(xiàng)目皆怕,包名為:org.libsdl.app毅舆,啟動(dòng)activity為:SDLActivity,因?yàn)檫@些信息都打包到了SDL2.so在了里面愈腾。

AS創(chuàng)建c/c++項(xiàng)目

更改activity為SDLActivity

2憋活、剛創(chuàng)建的項(xiàng)目還不能編譯成功,需要設(shè)置NDK路徑

添加NDK路徑

運(yùn)行AS C/C++默認(rèn)項(xiàng)目成功

二虱黄、改造默認(rèn)工程
1悦即、刪掉原來(lái)的main中cpp文件夾,創(chuàng)建jni文件夾(習(xí)慣了jni橱乱,用cpp文件夾也行)辜梳。然后在jni文件夾中創(chuàng)建armeabi文件夾,然后把在Android編譯SDL2和demo展示(2.0.5)中生成的libSDL2.so復(fù)制到armeabi文件夾中泳叠;再在jni文件夾中創(chuàng)建sdl文件夾作瞄,并將SDL中的頭文件include拷貝到里面;如圖:

導(dǎo)入SDL庫(kù)和頭文件

2危纫、在sdl中創(chuàng)建src文件夾宗挥,然后導(dǎo)入需要的文件:SDL中src根目錄下的所以文件、core文件夾中的android文件夾中所以文件(這里面就是實(shí)現(xiàn)的SDLActivity.java中的本地方法)种蝶、dynapi文件夾中所以文件属韧、main文件夾中android文件夾中的所有文件。如圖:

導(dǎo)入SDL中src需要文件

這樣就算改造完成了蛤吓。
三宵喂、編寫CMakeLists編譯腳本
1、更改生成的動(dòng)態(tài)庫(kù)名稱:sdlmain

add_library( # Sets the name of the library.
sdlmain
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/sdl/src/main/android/SDL_android_main.c
src/main/jni/SDL4Android.c)

其中SDL_android_main.c會(huì)調(diào)用SDL_android中的函數(shù)会傲,然后還作為入口方法調(diào)用我們自己SDL4Android.c文件中的main方法锅棕,SDL4Android.c是我們自己添加的c文件。
2淌山、導(dǎo)入SDL頭文件:
include_directories(src/main/jni/sdl/include)
3裸燎、添加SDL2.so庫(kù):

add_library( SDL2
SHARED
IMPORTED)
set_target_properties( SDL2
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jni/armeabi/libSDL2.so)

4、鏈接SDL2.so和libsdlmain.so

target_link_libraries( # Specifies the target library.
sdlmain
SDL2
# Links the target library to the log library
# included in the NDK.
${log-lib} )

這樣CMakeLists配置好了泼疑,全部如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
include_directories(src/main/jni/sdl/include)
add_library( # Sets the name of the library.
                    sdlmain
                    # Sets the library as a shared library.
                    SHARED
                    # Provides a relative path to your source file(s).
                    src/main/jni/sdl/src/main/android/SDL_android_main.c
                    src/main/jni/SDL4Android.c)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
                    log-lib
                    # Specifies the name of the NDK library that
                    # you want CMake to locate.
                    log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
add_library( SDL2
                    SHARED
                    IMPORTED)
set_target_properties( SDL2
                    PROPERTIES IMPORTED_LOCATION
                    ${CMAKE_SOURCE_DIR}/src/main/jni/armeabi/libSDL2.so)
target_link_libraries( # Specifies the target library.
                    sdlmain
                    SDL2
                    # Links the target library to the log library
                    # included in the NDK.
                    ${log-lib} )

四德绿、配置build.gradle,因?yàn)橹痪幾g了arm平臺(tái)的退渗,所以要指定一下只生成arm平臺(tái)和jniLibs目錄:

externalNativeBuild {
        cmake {
                cppFlags""
        }
        ndk {
                abiFilters"armeabi"
        }
}
sourceSets{
        main{
                jniLibs.srcDirs = ['src/main/jni']
        }
}

五移稳、最好把SDL4Android.c添加到j(luò)ni根目錄下:

#include
#include
#include
#include"SDL.h"
typedef structSprite
{
    SDL_Texture* texture;
    Uint16 w;
    Uint16 h;
} Sprite;
/* Adapted from SDL's testspriteminimal.c */
Sprite LoadSprite(const char* file,SDL_Renderer* renderer)
{
    Sprite result;
    result.texture = NULL;
    result.w =0;
    result.h =0;
    SDL_Surface* temp;
    /* Load the sprite image */
    temp = SDL_LoadBMP(file);
    if(temp == NULL)
    {
        fprintf(stderr,"Couldn't load %s: %s\n",file,SDL_GetError());
        returnresult;
    }
    result.w = temp->w;
    result.h = temp->h;
    /* Create texture from the image */
    result.texture = SDL_CreateTextureFromSurface(renderer,temp);
    if(!result.texture) {
        fprintf(stderr,"Couldn't create texture: %s\n",SDL_GetError());
        SDL_FreeSurface(temp);
        returnresult;
    }
    SDL_FreeSurface(temp);
    returnresult;
    }
    voiddraw(SDL_Window* window,SDL_Renderer* renderer,constSprite       sprite)
{
    intw,h;
    SDL_GetWindowSize(window,&w,&h);
    SDL_Rect destRect = {w/2- sprite.w/2,h/2- sprite.h/2,sprite.w,sprite.h};
    /* Blit the sprite onto the screen */
    SDL_RenderCopy(renderer,sprite.texture,NULL,&destRect);
    }
    intmain(intargc,char*argv[])
    {
        SDL_Window *window;
        SDL_Renderer *renderer;
        if(SDL_CreateWindowAndRenderer(0,0,0,&window,&renderer) <0)
        exit(2);
        Sprite sprite = LoadSprite("zx.bmp",renderer);
        if(sprite.texture == NULL)
            exit(2);
        /* Main render loop */
        Uint8 done =0;
        SDL_Event event;
        while(!done)
            {
                /* Check for events */
                while(SDL_PollEvent(&event))
                {
                    if(event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_FINGERDOWN)
                    {
                        //done = 1;
                    }
                }
                /* Draw a gray background */
                SDL_SetRenderDrawColor(renderer,0xA0,0xA0,0xA0,0xFF);
                SDL_RenderClear(renderer);
                draw(window,renderer,sprite);
                /* Update the screen! */
                SDL_RenderPresent(renderer);
                SDL_Delay(10);
            }
        exit(0);
}

然后把SDL中的SDLActivity.java中的代碼復(fù)制到我們的SDLActivity中。最好在main中添加資源文件assets会油,拷貝一張需要展示的圖片來(lái)運(yùn)行demo个粱,這樣就完成了移植:

[圖片上傳中。翻翩。都许。(8)]最終目錄結(jié)構(gòu)

運(yùn)行效果圖

就這樣了稻薇,有疑問(wèn)的地方可以留言,demo下載地址:Github:SDLforAndroidAS胶征,下一篇就寫SDL和FFmpeg的整合塞椎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市睛低,隨后出現(xiàn)的幾起案子忱屑,更是在濱河造成了極大的恐慌,老刑警劉巖暇昂,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莺戒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡急波,警方通過(guò)查閱死者的電腦和手機(jī)从铲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)澄暮,“玉大人名段,你說(shuō)我怎么就攤上這事∑茫” “怎么了伸辟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)馍刮。 經(jīng)常有香客問(wèn)我信夫,道長(zhǎng),這世上最難降的妖魔是什么卡啰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任静稻,我火速辦了婚禮,結(jié)果婚禮上匈辱,老公的妹妹穿的比我還像新娘振湾。我一直安慰自己,他們只是感情好亡脸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布押搪。 她就那樣靜靜地躺著,像睡著了一般浅碾。 火紅的嫁衣襯著肌膚如雪大州。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天及穗,我揣著相機(jī)與錄音摧茴,去河邊找鬼绵载。 笑死埂陆,一個(gè)胖子當(dāng)著我的面吹牛苛白,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播焚虱,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼购裙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鹃栽?” 一聲冷哼從身側(cè)響起躏率,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎民鼓,沒(méi)想到半個(gè)月后薇芝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丰嘉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年夯到,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饮亏。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耍贾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出路幸,到底是詐尸還是另有隱情荐开,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布简肴,位于F島的核電站晃听,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏砰识。R本人自食惡果不足惜杂伟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仍翰。 院中可真熱鬧赫粥,春花似錦、人聲如沸予借。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)灵迫。三九已至秦叛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瀑粥,已是汗流浹背挣跋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狞换,地道東北人避咆。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓舟肉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親查库。 傳聞我的和親對(duì)象是個(gè)殘疾皇子路媚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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