NativeActivity

环境搭建之创建nativeactivity

2021-04-01  本文已影响0人  _jetson_

Android-Studio-NativeActivity创建流程

1. Android-Studio和Android.mk方案 - 配置解析

1. 新建Android-studio工程

选择Native C++就可以了

2. 修改AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.opensl_triangle">

    <!-- 1. 没有java代码,设置android:hasCode="false" -->
    <application
        android:allowBackup="true"
        android:hasCode="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!-- 2. 将activity替换为nativeactivity -->
        <activity android:name="android.app.NativeActivity">
            <!-- 告诉nativeactivity它的库名为Hello_Triangle -->
            <meta-data android:name="android.app.lib_name"
                android:value="Hello_Triangle" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

3. ndk配置

1. 打开local.properties,添加:
ndk.dir=C\:\\Users\\jetson\\AppData\\Local\\Android\\Sdk\\ndk\\22.0.7026061

2. 打开gradle.properties,添加:
android.useDeprecatedNdk=true

3. 右键cpp文件夹,然后选link c++ project with gradle,选择jni下的Android.mk文件

4. 删除java文件夹

5. 配置Android.mk文件,调整文件夹

LOCAL_PATH          := $(call my-dir)
COMMON_PATH         := $(LOCAL_PATH)/../Common
COMMON_INC_PATH     := $(COMMON_PATH)/Include/
COMMON_SRC_PATH     := $(COMMON_PATH)/Source

include $(CLEAR_VARS)

# 要编译生成的库,和上面AndroidManifest.xml文件中<meta-data android:name="android.app.lib_name" android:value="Hello_Triangle" />配置一致
LOCAL_MODULE    := Hello_Triangle
# 定义ANDROID宏
LOCAL_CFLAGS    += -DANDROID


LOCAL_SRC_FILES := $(COMMON_SRC_PATH)/esShader.c \
                   $(COMMON_SRC_PATH)/esShapes.c \
                   $(COMMON_SRC_PATH)/esTransform.c \
                   $(COMMON_SRC_PATH)/esUtil.c \
                   $(COMMON_SRC_PATH)/esUtil_Android.c \
                   $(LOCAL_PATH)/Hello_Triangle.c
                   
                   

LOCAL_C_INCLUDES    := $(COMMON_INC_PATH)

# 需要链接EGL的库
LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv3

# 需要android_native_app_glue静态库
LOCAL_STATIC_LIBRARIES := android_native_app_glue

include $(BUILD_SHARED_LIBRARY)

# 需要import native_app_glue
$(call import-module,android/native_app_glue)

2. 源码解析

1. nativeactivity实现框架

1. 进入到android_main函数

///
//  android_main()
//
//    Main entrypoint for Android application
//
void android_main ( struct android_app *pApp )
{
   ESContext esContext;
   float lastTime;

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

   // Initialize the context
   memset ( &esContext, 0, sizeof ( ESContext ) );

   esContext.platformData = ( void * ) pApp->activity->assetManager;

   // 1. 设置轮询回调函数
   pApp->onAppCmd = HandleCommand;
   // 2. 设置私有的数据,可以在各个函数中获取,如回调函数中
   pApp->userData = &esContext;

   lastTime = GetCurrentTime();

   while ( 1 )
   {
      int ident;
      int events;
      struct android_poll_source *pSource;

       // 3. 调用onAppCmd中的回调函数来处理事件
      while ( ( ident = ALooper_pollAll ( 0, NULL, &events, ( void ** ) &pSource ) ) >= 0 )
      {

         if ( pSource != NULL )
         {
            pSource->process ( pApp, pSource );
         }

         if ( pApp->destroyRequested != 0 )
         {
            return;
         }

      }

      if ( esContext.eglNativeWindow == NULL )
      {
         continue;
      }

      // Call app update function
      if ( esContext.updateFunc != NULL )
      {
         float curTime = GetCurrentTime();
         float deltaTime =  ( curTime - lastTime );
         lastTime = curTime;
         esContext.updateFunc ( &esContext, deltaTime );
      }

       // 处理完事件之后,就进行绘制操作
      if ( esContext.drawFunc != NULL )
      {
         esContext.drawFunc ( &esContext );
         eglSwapBuffers ( esContext.eglDisplay, esContext.eglSurface );
      }
   }
}

2. 进入到HandleCommand函数中

static void HandleCommand ( struct android_app *pApp, int32_t cmd )
{
   ESContext *esContext = ( ESContext * ) pApp->userData;

   switch ( cmd )
   {
      case APP_CMD_SAVE_STATE:
         // the OS asked us to save the state of the app
         break;

      case APP_CMD_INIT_WINDOW:

         // 进行初始化操作
         esContext->eglNativeDisplay = EGL_DEFAULT_DISPLAY;
         esContext->eglNativeWindow = pApp->window;

         // Call the main entrypoint for the app
         if ( esMain ( esContext ) != GL_TRUE )
         {
            exit ( 0 ); //@TEMP better way to exit?
         }

         break;

      case APP_CMD_TERM_WINDOW:

         // Cleanup on shutdown
         if ( esContext->shutdownFunc != NULL )
         {
            esContext->shutdownFunc ( esContext );
         }

         if ( esContext->userData != NULL )
         {
            free ( esContext->userData );
         }

         memset ( esContext, 0, sizeof ( ESContext ) );
         break;

      case APP_CMD_LOST_FOCUS:
         // if the app lost focus, avoid unnecessary processing (like monitoring the accelerometer)
         break;

      case APP_CMD_GAINED_FOCUS:
         // bring back a certain functionality, like monitoring the accelerometer
         break;
   }
}

///
//  Global extern.  The application must declare this function
//  that runs the application.
//
extern int esMain ( ESContext *esContext );

//////////////////////////////////////////////////////////////////
//
//  Public Functions
//
//


综上所述,总的流程为:

初始化操作  ->  进行绘制  ->  退出

问题

1. avd emulator不支持OpenGL 3.0

点击emulator的... -> Settings -> Advanced -> OpenGL ES API level -> 选择3.1 -> 重启即可

参考

1. 示例:native-activity
https://developer.android.com/ndk/samples/sample_na?hl=zh-cn
2. native-activity的示例代码:
https://github.com/android/ndk-samples/tree/main/native-activity
3. NativeActivity开发示例-使用AndroidStudio和CMake
https://www.jianshu.com/p/f91ba94b60f4
4. avd emulator不支持OpenGL 3.0
https://stackoverflow.com/questions/40797975/android-emulator-and-opengl-es3-egl-bad-config
5. 源码位置:
上一篇 下一篇

猜你喜欢

热点阅读