在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 了解 native activity
多分辨率適配常用目錄
Android 開發(fā)環(huán)境(Eclipse+ADT+Android 5.0)
Android 原型設(shè)計工具探索
Makefile 快速入門
Android Studio的NDK開發(fā)
人臉檢測-靜態(tài)
getprop 與 dumpsys 命令
Maven 編譯開源二維碼掃描項目 zxing
畫布 Canvas
組合控件
Linux 下的模擬器硬件加速
讀取 Excel
android.hardware.camera2 使用指南
橫豎屏切換
Ubuntu 下切換 JDK 版本
拍照和錄像 with Camera
文本與布局
按鈕控制 ViewPager 的左右翻頁
用 TableLayout 偽裝表格顯示數(shù)據(jù)
Preference Activity 使用詳解
模擬器如何重啟?試試 Genymotion!
獲得屏幕物理尺寸、密度及分辨率
語音識別
了解 native activity
Android Studio 導(dǎo)入第三方類庫、jar 包和 so 庫
啟動另一個 App/apk 中的 Activity
APK 簽名
兩個開源的圖表/報表控件
android studio 導(dǎo)出 jar 包(Module)并獲得手機信息
圖片的 Base64 編解碼
混淆與反編譯
Android Studio 和 Gradle
Android 5.1 SDK 下載與配置
persistableMode 與 Activity 的持久化
adb 取出安裝在手機中的 apk
Android Studio 中的源代碼管理
Handler 使用中可能引發(fā)的內(nèi)存泄漏

了解 native activity

目錄(?)[+]

1.native activity 的意義

很多人覺得 Android 的 Fwk 提供的支持足夠好了,既然 Google 不推薦用 Ndk 開發(fā)為什么又放寬 Ndk 的限制而推出可以無 Java 開發(fā) Android App 呢?我的理解是不同的技術(shù)實現(xiàn)會有其適合的場景。

Ndk 的適用場景官方給出三點:1.平臺間的 App 移植 2.復(fù)用現(xiàn)有庫 3.對軟件性能要求較高的場合比如游戲等。那么 native activity 在十分適合游戲領(lǐng)域,比如 cocos-2dx 對其的使用。

2.初步了解 native activity

借助 SDK 提供的 NativeActivity 類,我們可以創(chuàng)建完全的本地 activity 而無須編寫 Java 代碼。

需要注意的是,即使是無 Java 代碼編寫的應(yīng)用仍然是跑(運行)在自己的虛擬機中以此與其他應(yīng)用隔離無不影響。你可以通過 JNI 的方式調(diào)用 Fwk 層的 API,有些像 sensor、輸入事件等操作可以直接調(diào)用本地接口(native interfaces)來完成(linc 注:這樣才高效嘛)。

有兩種方式可以實現(xiàn) native activity。

1)native_activity.h

2)android_native_app_glue

由于第二種方法啟用另一個線程處理回調(diào)和輸入事件,Ndk 的例子中就采用了這個實現(xiàn)方式。

3.Ndk 自帶的例子

這個程序主要演示根據(jù) sensor 的檢測結(jié)果在整個屏幕上繪制不同的顏色。

AndroidManifest.xml

為了正常使用 native activity,我們需要把 API 級別定在9及以上。

    <uses-sdk android:minSdkVersion="9" />

由于我們只使用 native code,將 android:hasCode 設(shè)為 false。

    <application android:label="@string/app_name" android:hasCode="false">

聲明 NativeActivity 類

        <activity android:name="android.app.NativeActivity"
                android:label="@string/app_name"
                android:configChanges="orientation|keyboardHidden">
            <!-- Tell NativeActivity the name of or .so -->
            <meta-data android:name="android.app.lib_name"
                    android:value="native-activity" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

注意 meta-data 中的 lib_name(native-activity)要與 Android.mk 中 LOCAL_MODULE 相同。

Android.mk

強調(diào)模塊名稱和源文件如下:

    LOCAL_MODULE    := native-activity
    LOCAL_SRC_FILES := main.c

外部庫的依賴

例子中用到了如下幾個外部庫,log、android(為 NDK 提供的標(biāo)準(zhǔn) Android 支持 API)、EGL(圖形 API)以及 OpenGL ES(android 用的 OpenGL,依賴 EGL)

書寫約定為上述庫前綴為 -l,如下:

    LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM

注意:

實際的庫文件名約定為前綴為 lib,后綴為.so。比如 log 庫文件名實際為 liblog.so。

這些庫的實際位置:

    <ndk>/platforms/android-<sdk_version>/arch-<abi>/usr/lib /

比如 liblog.so:

    $ locate liblog.so
    /opt/android-ndk-r10b/platforms/android-12/arch-arm/usr/lib/liblog.so
    /opt/android-ndk-r10b/platforms/android-12/arch-mips/usr/lib/liblog.so
    /opt/android-ndk-r10b/platforms/android-12/arch-x86/usr/lib/liblog.so
    /opt/android-ndk-r10b/platforms/android-13/arch-arm/usr/lib/liblog.so
    ...

靜態(tài)庫

本例用 android_native_app_glue 管理 NativeActivity 生命周期事件:

    LOCAL_STATIC_LIBRARIES := android_native_app_glue

我們需要告知編譯系統(tǒng)去 build 這個 static library,加上如下語句:

    $(call import-module,android/native_app_glue)

源代碼

主要源代碼文件只有一個,main.c。

引入的頭文件對應(yīng)在 Android.mk 中提到的,如下:

    #include <EGL/egl.h>
    #include <GLES/gl.h>

    #include <android/sensor.h>
    #include <android/log.h>
    #include <android_native_app_glue>

程序的入口是 android_main,通過 android_native_app_glue 調(diào)入并傳入一個預(yù)定義 state 結(jié)構(gòu)來管理 NativeActivity 的回調(diào)。

    void android_main(struct android_app* state)

結(jié)構(gòu) android_app 的定義參見/sources/android/native_app_glue/android_native_app_glue.h

接下來程序通過 glue 庫來處理事件隊列,參考如下代碼:

    struct engine engine;

    // Make sure glue isn't stripped.
    app_dummy();

    memset(&engine, 0, sizeof(engine));
    state->userData = &engine;
    state->onAppCmd = engine_handle_cmd;
    state->onInputEvent = engine_handle_input;
    engine.app = state;

準(zhǔn)備sensor

    // Prepare to monitor accelerometer
    engine.sensorManager = ASensorManager_getInstance();
    engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
            ASENSOR_TYPE_ACCELEROMETER);
    engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
            state->looper, LOOPER_ID_USER, NULL, NULL);

處理消息循環(huán)

    while (1) {
            // Read all pending events.
            int ident;
            int events;
            struct android_poll_source* source;

            // If not animating, we will block forever waiting for events.
            // If animating, we loop until all events are read, then continue
            // to draw the next frame of animation.
            while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL,
    &events,
                    (void**)&source)) >= 0) {

                // Process this event.
                if (source != NULL) {
                    source->process(state, source);
                }

                // If a sensor has data, process it now.
                if (ident == LOOPER_ID_USER) {
                    if (engine.accelerometerSensor != NULL) {
                        ASensorEvent event;
                        while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
                                &event, 1) > 0) {
                            LOGI("accelerometer: x=%f y=%f z=%f",
                                    event.acceleration.x, event.acceleration.y,
                                    event.acceleration.z);
                        }
                    }
                }

            // Check if we are exiting.
            if (state->destroyRequested != 0) {
                engine_term_display(&engine);
                return;
            }
        }

隊列為空時,調(diào)用 OpenGL 繪制屏幕

        if (engine.animating) {
            // Done with events; draw next animation frame.
            engine.state.angle += .01f;
            if (engine.state.angle > 1) {
                engine.state.angle = 0;
            }

            // Drawing is throttled to the screen update rate, so there
            // is no need to do timing here.
            engine_draw_frame(&engine);
        }

編譯

首先通過 NDK 編譯出 so 文件,在根目錄下直接執(zhí)行 ndk-build 即可:

    $ ndk-build
    [armeabi-v7a] Compile thumb  : native-activity <= main.c
    [armeabi-v7a] Compile thumb  : android_native_app_glue <= android_native_app_glue.c
    [armeabi-v7a] StaticLibrary  : libandroid_native_app_glue.a
    [armeabi-v7a] SharedLibrary  : libnative-activity.so
    [armeabi-v7a] Install: libnative-activity.so => libs/armeabi-v7a/libnative-activity.so

上述只摘錄出 armeabi-v7a 一個平臺的編譯 log,由于在 Application.mk 中沒有指明特定平臺,編譯系統(tǒng)會編譯出其他 armeabi、x86和 mips 平臺的 so。

然后再編譯 apk

我嘗試將工程向 AS 中導(dǎo)入,發(fā)現(xiàn)沒能配置好 gradle 編譯環(huán)境,無法編譯。

接著我就借助 ant 來編譯,參考如下步驟:

    $ android update project -p .
    Updated and renamed default.properties to project.properties
    Updated local.properties
    No project name specified, using Activity name 'NativeActivity'.
    If you wish to change it, edit the first line of build.xml.
    Added file ./build.xml
    Added file ./proguard-project.txt

    $ ant debug
    ...
    [echo] Debug Package: /opt/android-ndk-r10b/samples/native-activity/bin/NativeActivity-debug.apk
    ...
    BUILD SUCCESSFUL
    Total time: 3 seconds

最后

安裝運行吧!

    adb install /opt/android-ndk-r10b/samples/native-activity/bin/NativeActivity-debug.apk

參考:

http://blog.csdn.net/lincyang/article/details/40950153