Androidでは、c++のみで書かれるNativeActivityがあります。
github.com
これは通常のActivityと同じように、別のActivityから遷移させることが可能です。
今回は、この遷移についてやった内容を記事にしました。
サンプルプロジェクト
上のGoogleのサンプルのnative-activityサンプルを利用し、タッチイベントでNativeActivityに遷移を行うサンプルプロジェクトをGitHubに上げました。
github.com
これについて解説を行います。
NativeActivityを動かすための準備
今回は、先程貼ったGoogleのサンプルコードを、遷移先で動かそうと思います。
そのための準備を行っていきます。
main.cpp
Include C++ supportで自動生成されるnative-lib.cppは使わないので消します。
次に、プロジェクトのapp/src/main/cppフォルダに、サンプルプロジェクトのandroid-ndk/native-activity/app/src/main/cpp/main.cppを置きます。
CMakeLists.txtの編集
app/CMakeLists.txtの内容を、以下で置き換えます。
cmake_minimum_required(VERSION 3.4.1) # build native_app_glue as a static lib set(${CMAKE_C_FLAGS}, "${CMAKE_C_FLAGS}") add_library(native_app_glue STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) # now build app's shared lib set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall -Werror") # Export ANativeActivity_onCreate(), # Refer to: https://github.com/android-ndk/ndk/issues/381. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") add_library( native-activity SHARED src/main/cpp/main.cpp ) target_include_directories(native-activity PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue) find_library( log-lib log ) target_link_libraries( native-activity android native_app_glue EGL GLESv1_CM ${log-lib} )
大概がサンプルからのコピペで、ソースのパス位しか変えていません。
注意点としては、ビルド後のコードはnative-activityとなっている点でしょうか。
後述するAndroidManifest.xmlと、MainActivityでのloadLibraryでは、この名前を指定します。
build.gradleの編集
app/build.gradleのexternNativeBuild内、cmakeの項目に、abiFiltersとargumentsの追記を行い、以下のようにします。
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.wrongrong.changetonativeactivitysample" minSdkVersion 9 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64' arguments '-DANDROID_PLATFORM=android-9', '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static' } } } ︙
自動生成されるcmakeの項目にはcmakeのフラグについて記述(c++11を指定した場合、c++11に関する記述)がありますが、これは先程CMakeLists.txt内に記載を行ったので、消してしまって構いません。
AndroidManifest.xmlの編集
AndroidManifest.xmlの、application部に、activityに関して追記を行い、以下のようにします。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wrongrong.changetonativeactivitysample"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- Our activity is the built-in NativeActivity framework class. This will take care of integrating with our NDK code. --> <activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden"> <!-- Tell NativeActivity the name of our .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> ︙
MainActivity.java
ここまで行った変更に合わせ、MainActivity.javaの内容を変更します。
public class MainActivity extends AppCompatActivity { static { System.loadLibrary("native-activity"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.sample_text); } //タップイベントで、nativeactivityに遷移する @Override public boolean onTouchEvent(MotionEvent event) { Intent intent[] = new Intent[1]; intent[0] = new Intent(MainActivity.this, NativeActivity.class); startActivities(intent); return true; } }
ここまで紹介した手順によって、NativeActivityに遷移することができます。
アクティビティの遷移は、以下のサイトを参考にさせていただきました。
akira-watson.com
終わりに
今回はNativeActivityへの遷移まで実践しました。
このような場合のActivity間のデータのやり取りはどのようにするのかはまだ検証していないので、検証したらいつか記事にするかもしれません。