主頁 > 移動端開發 > 安卓JNI精細化講解,讓你徹底了解JNI(一):環境搭建與HelloWord

安卓JNI精細化講解,讓你徹底了解JNI(一):環境搭建與HelloWord

2020-09-15 20:50:19 移動端開發

目錄
1、基礎概念
├──1.1、JNI
├──1.2、NDK
├──1.3、CMake與ndk-build
2、環境搭建
3、Native C++ 專案(HelloWord案例)
├── 3.1、專案創建(java、kotlin)
├── 3.2、CMake的應用(詳細講解)
├── 3.3、ndk-build的應用(詳細講解)

1、基礎概念

1.1、JNI

JNI(Java Native Interface)Java本地介面,使得Java與C/C++具有互動能力

1.2、NDK

NDK(Native Development Kit) 本地開發工具包,允許使用原生語言(C和C++)來實作應用程式的部分功能

Android NDK開發的主要作用:

1、特定場景下,提升應用性能;
2、代碼保護,增加反編譯難度;
3、生成庫檔案,庫可重復使用,也便于平臺、專案間移植;

1.3、CMake與ndk-build

當我們基于NDK開發出native功能后,通常需要編譯成庫檔案,給Android專案使用,
目前,有兩種主流的編譯方式:CMake__與__ndk-build

__CMake__與__ndk-build__是兩種不同的編譯工具(與Android代碼和C/C++代碼無關)

CMake

CMake是Androidstudio2.2之后引入的跨平臺編譯工具(特點:簡單易用,2.2之后是默認的NDK編譯工具)

如何配置:
   1、創建CMakeLists.txt檔案,配置CMake必要引數;
   2、使用gradle配置CMakeLists.txt以及native相關引數;

如何編譯庫檔案:
   1、Android Studio執行Build即可;

ndk-build

ndk-build是NDK中包含的腳本工具(可在NDK目錄下找到該工具,為了方便使用,通常配置NDK的環境變數)

如何配置:
   1、創建Android.mk檔案,配置ndk-build必要引數;
   2、可選創建application.mk檔案,配置ndk-build引數 (該檔案的配置項可使用gradle的配置替代);
   3、使用gradle配置Android.mk以及native相關引數;

2、如何編譯庫檔案(兩種方式):
   1、Android Studio執行Build即可(執行了:Android.mk + gradle配置);
   2、也可在Terminal、Mac終端、cmd終端中通過ndk-build命令直接構建庫檔案(執行了:Android.mk)

2、環境搭建

JNI安裝
JNI 是JDK里的內容,電腦上正確安裝并配置JDK即可 (JDK1.1之后就正式支持了);

NDK安裝
可從官網自行下載、解壓到本地,也可基于AndroidStudio下載解壓到默認目錄;

編譯工具安裝
cmake 可基于AndroidStudio下載安裝;
ndk-build 是NDK里的腳本工具,NDK安裝好即可使用ndk-build;

當前演示,使用的Android Studio版本如下(當前最新版):

啟動Android Studio --> 打開SDK Manager --> SDK Tools,如下圖所示:

我們選擇NDK、CMake、LLDB(除錯Native時才會使用),選擇Apply進行安裝,等安裝成功后,NDK開發所依賴的環境也就都齊全了,

3、Native C++ 專案(HelloWord案例)

3.1、專案創建(java / kotlin)

新建專案,選擇 Native C++,如下圖:

新創建的專案,默認已包含完整的native 示例代碼、cmake配置 ,如下圖:

這樣,我們就可以自己定義Java native方法,并在cpp目錄中寫native實作了,很方便,

但是,當我們寫完native的實作代碼,希望運行APP,查看JNI的互動效果,此時,就需要使用編譯工具了,咱們還是先看一下Android Studio默認的Native編譯方式吧:CMake

3.2、CMake的應用

在CMake編譯之前,咱們應該先做哪些準備作業?

1、NDK環境是否配置正確?
-- 如果未配置正確是無法進行C/C++開發的,更不用說CMake編譯了

2、C/C++功能是否實作? 
-- 此次演示主要使用系統默認創建的native-lib.cpp檔案,關于具體如何實作:后續文章再詳細講解

3、CMakeLists.txt是否創建并正確配置? 
-- 該檔案是CMake工具編譯的基礎,未配置或配置項錯誤,均會影響編譯結果

4、gradle是否正確配置?
-- gradle配置也是CMake工具編譯的基礎,未配置或配置項錯誤,均會影響編譯結果

除此之外,咱們還應該學習CMake的哪些重要知識?

1、CMake工具編譯生成的庫檔案默認在什么位置?apk中庫檔案又是在什么位置?
2、CMake工具如何指定編譯生成的庫檔案位置?
3、CMake工具如何指定生成不同CPU平臺對應的庫檔案?

帶著這些問題,咱們開始CMake之旅吧:

3.2.1、NDK環境檢查

編譯前,建議先檢查下工程的NDK配置情況(不然容易報一些亂七八糟的錯誤):
File --> Project Structure --> SDK Location,如下圖(我本地的Android Studio默認沒有給配置NDK路徑,那么,需要自己手動指定一下):

3.2.2、C/C++功能實作

因為本節主講CMake編譯工具,代碼就不單獨寫了,咱們直接使用工程默認生成的native-liv.cpp,簡單調整一下native實作方法的代碼吧(修改回傳文本資訊):

因Native C++工程默認已配置好了CMakeLists.txt和gradle,所以咱們可直接運行工程看效果,如下圖:

JNI互動效果我們已經看到了,說明CMake編譯成功了,那么,這究竟是怎么做到的呢?咱們接著分析一下吧:

3.2.3、CMake生成的庫檔案與apk中的庫檔案

安卓工程編譯時,會執行CMake編譯,在 工程/app/build/.../cmake/ 中會產生對應的so檔案,如下圖:

繼續編譯安卓工程,會根據build中的內容,生成我們的*.apk安裝包檔案,我們找到、反編譯apk安裝包檔案,查找so庫檔案,原來在apk安裝包中,so庫都被存放在lib目錄中,如下圖:

3.2.4、CMake是如何編譯生成so庫的呢?

在前面介紹CMake定義時,提到了CMake是基于CMakeLists.txt檔案和gradle配置實作編譯Native類的,那么,咱們先來看一下CMakeLists.txt檔案吧:

#cmake最低版本要求
cmake_minimum_required(VERSION 3.4.1)

#添加庫
add_library(
        # 庫名
        native-lib

        # 型別:
        # SHARED 是指動態庫,對應的是.so檔案
        # STATIC 是指靜態庫,對應的是.a檔案
        # 其他型別:略
        SHARED

        # native類路徑
        native-lib.cpp)

# 查找依賴庫
find_library( 
        # 依賴庫別名
        log-lib

        # 希望加到本地的NDK庫名稱,log指NDK的日志庫
        log)


# 鏈接庫,建立關系( 此處就是指把log-lib 鏈接給 native-lib使用 )
target_link_libraries( 
        # 目標庫名稱(native-lib 是咱們要生成的so庫)
        native-lib

        # 要鏈接的庫(log-lib 是上面查找的log庫)
        ${log-lib})

實際上,CMakeList.txt可配置的內容遠不止這些,如:so輸出目錄,生成規則等等,有需要的同學可查下官網,

接著,咱們再看一下app的gradle又是如何配置CMake的呢?

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.1"
    defaultConfig {
        applicationId "com.qxc.testnativec"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        //定義cmake默認配置屬性
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    
    //定義cmake對應的CMakeList.txt路徑(重要)
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

實際上,gradle可配置的cmake內容也遠不止這些,如:abi、cppFlags、arguments等,有需要的同學可查下官網,

3.2.5、如何指定庫檔案的輸出目錄?

如果希望將so庫生成到特定目錄,并讓專案直接使用該目錄下的so,應該如何配置呢?
比較簡單:需要在CMakeList.txt中配置庫的輸出路徑資訊,即:

CMAKE_LIBRARY_OUTPUT_DIRECTORY

# cmake最低版本要求
cmake_minimum_required(VERSION 3.4.1)

# 配置庫生成路徑
# CMAKE_CURRENT_SOURCE_DIR是指 cmake庫的源路徑,通常是build/.../cmake/
# /../jniLibs/是指與CMakeList.txt所在目錄的同級目錄:jniLibs (如果沒有會新建)
# ANDROID_ABI 生成庫檔案時,采用gradle配置的ABI策略(即:生成哪些平臺對應的庫檔案)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

# 添加庫
add_library( # 庫名
        native-lib

        # 型別:
        # SHARED 是指動態庫,對應的是.so檔案
        # STATIC 是指靜態庫,對應的是.a檔案
        # 其他型別:略
        SHARED

        # native類路徑
        native-lib.cpp)

# 查找依賴庫
find_library(
        # 依賴庫別名
        log-lib

        # 希望加到本地的NDK庫名稱,log指NDK的日志庫
        log)


# 鏈接庫,建立關系( 此處就是指把log-lib 鏈接給native-lib使用 )
target_link_libraries(
        # 目標庫名稱(native-lib就是咱們要生成的so庫)
        native-lib

        # 要鏈接的庫(上面查找的log庫)
        ${log-lib})

還需要在gradle中配置 jniLibs.srcDirs 屬性(即:指定了lib庫目錄):

sourceSets {
        main {
            jniLibs.srcDirs = ['jniLibs']//指定lib庫目錄
        }
    }

接著,重新build就會在cpp相同目錄級別位置生成jniLibs目錄,so庫也在其中了:

注意事項:
1、配置了CMAKE_CURRENT_SOURCE_DIR,并非表示編譯時直接將so生成在該目錄中,實際編譯時,so檔案仍然是
先生成在build/.../cmake/中,然后再拷貝到目標目錄中的

2、如果只配置了CMAKE_CURRENT_SOURCE_DIR,并未在gradle中配置 jniLibs.srcDirs,也會有問題,如下:
More than one file was found with OS independent path 'lib/arm64-v8a/libnative-lib.so'

此問題是指:在編譯生成apk時,發現了多個so目錄,android studio不知道使用哪一個了,所以需要咱們
告訴android studio當前工程使用的是jniLibs目錄,而非build/.../cmake/目錄
3.2.5、如何生成指定CPU平臺對應的庫檔案呢?

我們可以在cmake中設定abiFilters,也可在ndk中設定abiFilters,效果是一樣的:

defaultConfig {
        applicationId "com.qxc.testnativec"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
                abiFilters "arm64-v8a"
            }
        }
    }
defaultConfig {
        applicationId "com.qxc.testnativec"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
        ndk {
            abiFilters "arm64-v8a"
        }
    }

按照新的配置,我們重新運行工程,如下圖:

再反編譯看下工程,果然只有arm64-v8a的so庫了,不過庫檔案在apk中仍然是放在lib目錄,而非jniLibs(其實也很好理解,jniLibs只是我們本地的目錄,便于我們管理庫檔案,真正生成apk時,仍然會按照lib目錄放置庫檔案),如下圖:

至此,CMake的主要技術點都講完了,接下來咱們看下NDK-Build吧~

3.3、ndk-build的應用

在ndk-build編譯之前,咱們又應該先做哪些準備作業?

1、ndk-build環境變數是否正確配置?
-- 如果未配置,是無法在cmd、Mac終端、Terminal中使用ndk-build命令的(會報錯:找不到命令)

2、NDK環境是否配置正確?
-- 如果未配置正確是無法進行C/C++開發的,更不用說ndk-build編譯了

3、C/C++功能是否實作?
-- 此次演示主要使用系統默認創建的native-lib.cpp檔案,關于具體如何實作:后續文章再詳細講解
-- 注意:為了與CMake區分,咱們新建一個“jni”目錄存放C/C++檔案、組態檔吧

4、Android.mk是否創建并正確配置? 
-- 該檔案是ndk-build工具編譯的基礎,未配置或配置項錯誤,均會影響編譯結果

5、gradle是否正確配置?(可選項,如果通過cmd、Mac終端、Terminal執行ndk-build,可忽略)
-- gradle配置也是ndk-build工具編譯的基礎,未配置或配置項錯誤,均會影響編譯結果

6、Application.mk是否創建并正確配置?(可選項,一般配ABI、版本,這些項均可在gradle中配置)
-- 該檔案也是ndk-build工具編譯的基礎,未配置或配置項錯誤,均會影響編譯結果

除此之外,咱們還應該學習ndk-build的哪些重要知識?

1、ndk-build工具如何指定編譯生成的庫檔案位置?
2、ndk-build工具如何指定生成不同CPU平臺對應的庫檔案?

帶著這些問題,咱們繼續ndk-build之旅吧:

3.3.1、環境變數配置

介紹NDK-Build定義時,提到了其實它是NDK的腳本工具,那么,咱們還是先進NDK目錄找一下吧,ndk-build工具的位置如下圖:

如果我們希望任意情況下都能便捷的使用這種腳本工具,通常做法是配置其環境變數,否則我們在cmd、Mac終端、Terminal中執行 ndk-build 命令時,會報錯:“未找到命令”

配置NDK的環境變數,也很簡單,以Mac電腦舉例(如果是Windows電腦,網上也有很多關于配置環境變數的文章,如果有需要可自行查下):

1、打開命令終端,輸入命令: open -e .bash_profile,打開bash_profile組態檔

2、寫入如下內容(NDK_HOME指向 ndk-build 所在路徑):
export NDK_HOME=/Users/xc/SDK/android-sdk-macosx/ndk/20.1.5948944
export PATH=$PATH:$NDK_HOME

3、生效.bash_profile配置
source .bash_profile

當我們在cmd、Mac終端、Terminal中執行 ndk-build 命令時,如果出現下圖所示內容,則代表配置成功了:

3.3.2、C/C++功能實作

咱們使用比較常用的一種ndk-build方式吧:ndk-build + Android.mk + gradle配置

專案中新建jni目錄,拷貝一份CMake的代碼實作吧:

1、新建jni目錄
2、拷貝cpp/native-lib.cpp 至 jni目錄下
3、重命名為haha.cpp (與CMake區分)
4、調整一下native實作方法的文本(與CMake運行效果區分)
5、新建Android.mk檔案

接著,撰寫Android.mk檔案內容:

#表示Android.mk所在目錄
LOCAL_PATH := $(call my-dir)

#CLEAR_VARS變數指向特殊 GNU Makefile,用于清除部分LOCAL_變數
include $(CLEAR_VARS)

#模塊名稱
LOCAL_MODULE    := haha
#構建系統用于生成模塊的源檔案串列
LOCAL_SRC_FILES := haha.cpp

#BUILD_SHARED_LIBRARY 表示.so動態庫
#BUILD_STATIC_LIBRARY 表示.a靜態庫
include $(BUILD_SHARED_LIBRARY)

配置gradle:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.aaa.testnative"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        //定義ndkBuild默認配置屬性
        externalNativeBuild {
            ndkBuild {
                cppFlags ""
            }
        }
    }
   
    //定義ndkBuild對應的Android.mk路徑(重要)
    externalNativeBuild {
        ndkBuild{
            path "src/main/jni/Android.mk"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

現在,native代碼、ndk-build配置都完成了,咱們運行看一下效果吧,如下圖:

3.3.4、如何指定庫檔案的輸出目錄?

通常,可在Android.mk檔案中配置NDK_APP_DST_DIR
指定源目錄與輸出目錄(與CMake類似)

#表示Android.mk所在目錄
LOCAL_PATH := $(call my-dir)

#設定庫檔案的輸入目錄
#輸出目錄 ../jniLibs/
#源目錄 $(TARGET_ARCH_ABI)
NDK_APP_DST_DIR=../jniLibs/$(TARGET_ARCH_ABI)

#CLEAR_VARS變數指向特殊 GNU Makefile,用于清除部分LOCAL_變數
include $(CLEAR_VARS)

#模塊名稱
LOCAL_MODULE    := haha
#構建系統用于生成模塊的源檔案串列
LOCAL_SRC_FILES := haha.cpp

#BUILD_SHARED_LIBRARY 表示.so動態庫
#BUILD_STATIC_LIBRARY 表示.a靜態庫
include $(BUILD_SHARED_LIBRARY)

3.3.5、如何生成指定CPU平臺對應的庫檔案呢?

可在gradle中配置abiFilters(與Cmake類似)

externalNativeBuild {
            ndkBuild {
                cppFlags ""
                abiFilters "arm64-v8a"
            }
        }
externalNativeBuild {
            ndkBuild {
                cppFlags ""
            }
        }
  ndk {
            abiFilters "arm64-v8a"
        }
3.3.6、如何在Terminal中直接通過ndk-build命令構建庫檔案呢?

除了執行AndroidStudio的build命令,基于gradle配置 + Android.mk編譯生成庫檔案,我們還可以在cmd、Mac 終端、Terminal中直接通過ndk-build命令構建庫檔案,此處以Terminal為例進行演示吧:

先進入包含Android.mk檔案的jni目錄(Android Studio中可直接選中jni目錄并拖拽到Terminal中,會自動跳轉到該目錄),再執行ndk-build命令,如下圖:

同樣,編譯也成功了,如下圖:

因是直接在Terminal中執行了ndk-build命令,所以只會根據Android.mk進行編譯(不包含gradle配置內容,也就不會執行abiFilters過濾),生成了所有默認CPU平臺的so庫檔案,

ndk-build命令其實也可以配上一些引數使用,此處就不再詳解了,日常開發時,還是建議選擇CMake作為Native編譯工具,因為是安卓主推的,而且更簡單一些,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/50058.html

標籤:Android

上一篇:Kotlin Coroutines不復雜, 我來幫你理一理

下一篇:安卓JNI精細化講解,讓你徹底了解JNI(二):用法決議

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more