Android老版本到AS3.1中遇到的問題與相應(yīng)的解決辦法

很久之前為老東家做了個android視頻監(jiān)控軟件,老東家的視頻設(shè)備的協(xié)議是私有的,沒有用標(biāo)準(zhǔn)的RTMP、RTSP、HLS等標(biāo)準(zhǔn)視頻流協(xié)議,幾年前此協(xié)議從攝像機(jī)前端,服務(wù)器接收與轉(zhuǎn)發(fā)以及客戶端都是我寫的,使用的是Boost的asio網(wǎng)絡(luò)框架,當(dāng)然也用了一些其他的Boost特性;解碼使用的是ffmpeg的標(biāo)準(zhǔn)264庫,顯示使用的是android的opengl顯示庫。

? 這篇文章里主要還是描述as升級后遇到的一些問題與解決方法,為了以后遇到類似問題不再從頭做起,算作是做個記錄。

問題1.org.apache.http找不到

import org.apache.http.*

提示此文件不包含了,解決很簡單,在app的gradle腳本中添加useLibrary 'org.apache.http.legacy'

android { 
    *****
        useLibrary 'org.apache.http.legacy'
    *****
}

問題2.cmake使用

之前編譯c文件使用的是ndk,現(xiàn)在as升級到3.0之后,支持cmake了,修改代碼后,可以直接編譯運(yùn)行,省去了先編譯c(c++)文件的煩惱,那就用cmake編譯文件吧,之前做過cmake 的android編譯,不過已經(jīng)是去年的事情了,再開始做的時候,又無從下手,從現(xiàn)有工程添加cmake編譯支持,需要以下幾個步驟

  1. 在app的gradle文件中添加相關(guān)的cmake支持,我的gradle關(guān)于cmake的支持如下
android {
    compileSdkVersion 27

    defaultConfig {
        applicationId "xxxxxx"
        ***********************
        ndk {
            // 設(shè)置支持的SO庫架構(gòu)
            abiFilters 'armeabi-v7a'//, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
        }
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_DISABLE_FATAL_LINKER_WARNINGS=TRUE", "-DANDROID_STL=c++_shared"
                cppFlags " -frtti -fexceptions"
            }
        }
    }
    
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
   ********
}

cmake放在app模塊文件夾內(nèi),具體路徑為

/工程路徑/app/CMakeLists.txt

cpp文件路徑為

/工程路徑/app/src/main/cpp/c或者c++文件

CMakeLists.txt為

# 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)
set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp)
set(BOOST_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp/boost)
set(FFMPEG_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg)

ADD_DEFINITIONS(
 -O3 -g -W -Wall
 -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wreserved-user-defined-literal
 -Wno-deprecated -Woverloaded-virtual -Wwrite-strings
 -Wl,–no-warn-shared-textrel
 -fPIC
)

add_library(ffmpeg SHARED IMPORTED)
set_target_properties(ffmpeg PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/lib/libffmpeg.so)

add_definitions("-DBOOST_ERROR_CODE_HEADER_ONLY -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_SYSTEM_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB")

add_library(boost_system STATIC IMPORTED)
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION ${BOOST_DIR}/lib/libboost_system-clang-mt-a32-1_66.a)

add_library(boost_thread STATIC IMPORTED)
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION ${BOOST_DIR}/lib/libboost_thread-clang-mt-a32-1_66.a)

add_library(boost_atomic STATIC IMPORTED)
set_target_properties(boost_atomic PROPERTIES IMPORTED_LOCATION ${BOOST_DIR}/lib/libboost_atomic-clang-mt-a32-1_66.a)



set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-fatal-warnings")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fPIC")
add_library( # Sets the name of the library.
             ivs
             # Sets the library as a shared library.
             SHARED
             # Provides a relative path to your source file(s).
              ${SOURCE_DIR}/ivsMain.cpp
              ${SOURCE_DIR}/gsession.cpp
              ${SOURCE_DIR}/render.cpp
              ${SOURCE_DIR}/sn.cpp
             )

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 )

target_include_directories(ivs PRIVATE
                           ${BOOST_DIR}/include/boost-1_66/
                           ${FFMPEG_DIR}/include/)


# 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.

target_link_libraries( # Specifies the target library.
                       ivs
                       ffmpeg
                       boost_thread
                       boost_system
                       boost_atomic
                       GLESv1_CM
                       GLESv2
                       EGL
                       OpenSLES
                       android
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

關(guān)于cmake的使用,可以參考Android Studio Cmake

問題3.boost庫的編譯

很久之前編譯過Android平臺的boost庫,幾年沒有碰,完全忘記了,此次編譯,使用的是github上的一個開源編譯項(xiàng)目 https://github.com/moritz-wundke/Boost-for-Android,把工程git下來,開始編譯,編譯shell

./build-android.sh $(NDK_ROOT)--$(NDK_ROOT)為你的ndk路徑,比如我的路徑為/opt/android/android-ndk-r16b

花很久的時間編譯完成,但是靜態(tài)鏈接庫,產(chǎn)生error

no archive symbol table (run ranlib) 

我的操作系統(tǒng)是macOS 10.14.4,,此github工程的issues提到過mac這個問題,期間我也嘗試了其他的方法,都不行,算了,轉(zhuǎn)到linux平臺去編譯就行了吧,東方不亮西方亮,不求甚解,編譯腳本

./build-android.sh ndk_dir --with-libraries=thread,system,random --arch=arm64-v8a,armeabi-v7a

我的工程里只用到了thread和system庫,沒有必要全部編譯,全部編譯等的時間太長,工程里也只用了armeabi-v7a架構(gòu),2011年一般的手機(jī)都支持armeabi-v7a,多編譯一個arm64-v8a萬一以后用到,反正也沒有多長時間

問題4.boost庫的頭文件鏈接問題

cmake中的腳本:

set(BOOST_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp/boost)
target_include_directories(ivs PRIVATE
                           ${BOOST_DIR}/include/boost-1_66/)

這個頭文件大概100多兆,鏈接之后,as直接卡在 loading symbols,大概一兩個小時,只能干等,關(guān)鍵是鏈接完畢之后,想操作as,基本也是處于卡死狀態(tài),沒有辦法繼續(xù)編碼下去,這個時候boost的bcp工具來了,參考 boost工具bcp編譯,使用方式

$./dist/bin/bcp boost/algorithm/string.hpp algorithm_inc/

你的c或者cpp文件里包含了什么,就運(yùn)行一下,比如我的工程里包含了

#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include<boost/function.hpp>
#include<boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>  

那么執(zhí)行

$./dist/bin/bcp boost/bind.hpp output/
$./dist/bin/bcp boost/asio.hpp output/
......
$./dist/bin/bcp boost/date_time/posix_time/posix_time_types.hpp output/

生成了頭文件只有20多兆,不能說瞬間 loading symbols完畢,幾分鐘之內(nèi)吧,可以接受,而且之后操作as也沒有卡頓現(xiàn)象,其實(shí)使用bcp也可以鏈接靜態(tài)庫,應(yīng)該可以包含實(shí)現(xiàn)文件,我嫌麻煩,直接鏈接了靜態(tài)庫

問題5.ffmpeg庫升級一些函數(shù)和結(jié)構(gòu)找不到

比如PIX_FMT_RGB565類型沒有了,相應(yīng)的是AV_PIX_FMT_RGB565替代了,網(wǎng)上資料很多,不展開了

問題6. opengles中的glDrawTexiOES函數(shù)

glDrawTexiOES not defined,但是glext.h已經(jīng)包含了,注意在包含glext.h前加上

glext.h

#define GL_GLEXT_PROTOTYPES //包含頭文件前添加
#include <GLES/glext.h>

問題7. android java調(diào)用c中實(shí)現(xiàn),找不到相關(guān)函數(shù)

比如java中有個函數(shù)

glInit(String path)

就是找不到,我的c++中實(shí)現(xiàn)

extern "C" JNIEXPORT void JNICALL com_carvedge_ivs_LIB_glInit(JNIEnv *env, jclass clazz,jstring jpath)

找了好久,以為是庫的問題,最后發(fā)現(xiàn)是在c實(shí)現(xiàn)中少了一個Java,正確的應(yīng)該是

extern "C" JNIEXPORT void JNICALL Java_com_carvedge_ivs_LIB_glInit(JNIEnv *env, jclass clazz,jstring jpath)

大概就這么多,以后想起來其他的再補(bǔ)充

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容