åé¡ã®èšå®ãé€ããç¡é¢ä¿ã§ãã
次ã®èšäºã®æ£ããæ±ºå®ã
ããã«ã¡ã¯ããããããã¹ïŒ ãã®èšäºã§ã¯ãqtãšandroid studioã§ã®çµéšã«ã€ããŠã話ããããšæããŸãã ã€ãŸããã©ã®ããã«qtã§ããã¹ããæç»ãããããAndroid Studioã«è»¢éããå¿
èŠããã£ããã§ãã ã¿ã¹ã¯ã®åçŽãã«ãããããããããã解決ããã®ã«ããªãæéããããã誰ããã©ããã§å€ãã®æéãç¯çŽãããããããŸããã ããæå³ããã®èšäºã¯èªè»¢è»ãçºæãããšäž»åŒµããŠããããã€ã³ã¿ãŒãããäžã§è§£æ±ºçãèŠã€ããããšãã§ããªãã£ãã èª°ãæ°ã«ããªã-ãã£ãããžããããïŒ
ã¿ã¹ã¯èªäœã«ã€ããŠå°ã
æè¿ãiosããandroidã«ã¢ããªã±ãŒã·ã§ã³ãç§»æ€ããã¿ã¹ã¯ã«çŽé¢ããŸããã ç§»æ€æã®äž»ãªçã¿ã¯ãSDKã¢ããªã±ãŒã·ã§ã³ã§ã®äœæ¥ã§ããã ããã¯Qtã§æžãããŠãããããã¹ã/ç¢å°/ãšãªã¢ãªã©ãæç»ããããã«äœ¿çšãããŠããŸããã ã€ãŸããã¢ããªã±ãŒã·ã§ã³ã¯
ç®çcã§èšè¿°ãããqtã©ã€ãã©ãªã䜿çšããŸããããqtãããžã§ã¯ãã§ã¯ãããŸããã§ããã ãããã£ãŠãæåã«ç»å Žããã®ã¯éçºç°å¢ã§ããã ç§ã¯ãã®ããžãã¹ã«å®å
šã«æ
£ããŠããªãã®ã§ãç§ã®éžæã¯Android Studioã«ãããŸããã ããã§ããç§ã«ãšã£ãŠã¯ã°ã©ãã£ã«ã«ã€ã³ã¿ãŒãã§ã€ã¹å
šäœãAndroidã¹ã¿ãžãªã§è¡ãæ¹ãé©åã§ãããqtshnoe SDKã¯ã³ã³ãã¥ãŒãã£ã³ã°ã¿ã¹ã¯ãå®è¡ããŸãã ã€ã³ã¿ãŒãããã§ã¯ãqtãAndroidã«äœ¿çšããããšã«ã€ããŠããŸãæžãããŠããŸããããããã§ã¯qtãšandroid studioãåéã«ããäœæ¥ãè¡ããŸããã ãããšé£æºããã«ã¯ãAndroid NDKã䜿çšããJNIã䜿ââçšããŠãã¹ãŠãå®è£
ããŸãã JNIã§ã®äœæ¥ã¯ãããèªäœããªãè峿·±ããã®ã§ãã neteã§ã¯ããã®ãããã¯ã«é¢ããå€ãã®èšäºãèŠã€ããããšãã§ããŸãïŒããšãã°ã
ãã®çŽ æŽããããµã€ã¯ã« ïŒã ãã ããJNIãQtã§äœ¿çšãããšããç¹ã§ã¯ãJNIã«èå³ããããŸãã ç¹°ãè¿ããŸãããåé¡ã¯äœã§ããïŒ é«åºŠãªsorsasã䜿çšããå
±æã©ã€ãã©ãªãäœæããAndroidã¹ã¿ãžãªã®ãããžã§ã¯ãã«æ¥ç¶ããŠå©çãåŸãŸãïŒ ããã§ã
äŸãšããŠããã«ã ãããŠããããæ¥œãã¿ãå§ãŸããŸã...
Android Studioã§QTã䜿çšãã
èŠããŠããããã«ãç§ã¯ãããäžã«ç€ºãã
ããã¯Qtã§æžãããããã¹ã/ç¢å°/ãšãªã¢ãšä»ã®ãã¹ãŠãæãããã«äœ¿çšãããŸãã
ã
QTã§ã°ã©ãã£ãã¯ããªããã£ããæç»ããããã«ãQApplicationãŸãã¯QGuiApplicationã®ã€ã³ã¹ã¿ã³ã¹ãäœæããå¿
èŠã¯ãããŸããã QCoreApplicationã§ãã-ãããŠåœŒã¯å¿
èŠãããŸããïŒ ãã ããQApplicationãŸãã¯QGuiApplicationãªãã§ããã¹ããæç»ããå Žåã¯ãäœãã§ããŸããã ããã§ã¯ãåé¡ã¯äœã§ããïŒ ãã®åé¡ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºããããšãã«çºçããŸãã
QApplication a(argc, argv);
ã©ã€ãã©ãªãäœæããå ŽåãQApplicationã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºã颿°ãã©ã€ãã©ãªã«ãããAndroid Studioã¢ããªã±ãŒã·ã§ã³ããJNIãä»ããŠåŒã³åºããããã«æ¬¡ã®ããã«èšããŸãã
ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãQtãã©ãããã©ãŒã ãã©ã°ã€ã³ãAndroidããèŠã€ããããªãããããŒãã§ããªãã£ããããèµ·åã«å€±æããŸããã
誰ã®ããã§ããïŒ
ã¯ã©ã·ãã¯ããŒãžã§ã³ã ææãåŠã¶ïŒ
ç§ãæåã«ããããšæ±ºããã®ã¯ãã€ã³ã¿ãŒãããäžã®åé¡ã®è§£æ±ºçãã°ãŒã°ã«ã«ããããšã§ããã å®å
šã«äžèŽãããã®ã¯èŠã€ãããŸããã§ããããããªãå€ãã®æçš¿ã§ãWindowsãã©ã°ã€ã³ã®åæ§ã®åé¡ã«ã€ããŠèŠæ
ãå¯ããããŸããã ããã§ã
ããã§èšåãããã¹ãŠã詊ããŸããããæ®å¿µãªãã解決çã¯ãããŸããã§ããïŒç§ã®ããã«åããŠããŸãïŒïŒ
ç§ã®è³ªåãžã®çããæ¢ããŠãã¢ã³ããã€ãã®äžã§èè
qtãçè§£ããã®ã§ãç§ã¯ãã®ãããªããªãå¥åŠãª
ããã°ã«åºäŒããŸããã ããã°ã¯éåžžã«è峿·±ããã®ã§ãããèè
ã¯ïŒããã§ããç§èŠïŒC ++ããã®éçºãšqtäœæè
ããã®ãã¹ãŠã®è¯ãç©ã®ç«ã¡äžãã«çŠç¹ãåœãŠãŠããŸãã æ£çŽãªãšããããã®ã¢ãããŒãã¯1ã€ã®çç±ã§ç§ã«ã¯åããŠããŸããã§ããïŒQtããJavaéšåããããã°ããããšã¯ã»ãšãã©äžå¯èœã§ãïŒã³ãŒããã³ã³ãã€ã«ããŠãããAndroidã¹ã¿ãžãªããã®æ·»ä»ãã¡ã€ã«ãåŸ
ã£ãŠãããããäœãèµ·ãã£ãŠããã®ããèŠãããšãã§ããŸãïŒãã«ã¹ã¿ã ãã¥ãŒãéåæã¿ã¹ã¯ããããããããqtãããžã§ã¯ãã«å
¥ããŠæ£åžžã«ãããã°ããã«ã¯ã©ãããã°ããã§ããïŒ æ£çŽãªãšãããããããŸããã
å®éš
Qtã¢ããªã±ãŒã·ã§ã³ãäœæããŠãAndroidã§å®è¡ããããšããŸããã ç§ã¯ãããqt-creatorã§å®è¡ããŸããããå¥åŠãªããšã«ãå®å
šã«èµ·åããŸããã ãããã§ã¹ããã°ã©ãã«ãã¢ããªã±ãŒã·ã§ã³ã³ãŒããã©ã®ããã«é
眮ãããŠãããããã詳ãã調ã¹å§ããŸããã ãããã§ã¹ãã§ãã®ãããªè峿·±ãããšãããããŸããã
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/> <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/> <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/> <meta-data android:name="android.app.use_local_qt_libs" android:value="1"/> <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> <meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so"/> <meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidAccessibility.jar:jar/QtAndroid-bundled.jar:jar/QtAndroidAccessibility-bundled.jar"/> <meta-data android:name="android.app.static_init_classes" android:value=""/>
ã€ãŸãããã®æå³ã¯æç¢ºã§ãã apkã¢ããªã±ãŒã·ã§ã³ããã«ããããšããqtã©ã€ãã©ãªãapkå
ã«é
眮ããå¿
èŠãããããšã瀺ããããããã¢ããªã±ãŒã·ã§ã³ã«ããŒãããå¿
èŠãããããšã瀺ããŸããã 察å¿ããjar-sãandroidã®ãããžã§ã¯ãã«æ¥ç¶ããqtã«ãããã®ãandroidãããã§ã¹ãã«ç»é²ããjniLibsãã©ã«ããŒã«qtny.soãã©ã°ã€ã³ãé
眮ããŠã广ã¯ãããŸããã§ããã
åŠç¿ãã©ã°ã€ã³
ç§ã¯æçµçã«ããã®äžå¹žãªãã©ã°ã€ã³libqtforandroid.soïŒQApplicationãäœæããåïŒãjavaã«ãã£ãŠããŒãããããšããŸããã
System.loadLibraryïŒ "plugins_platforms_android_libqtforandroid"ïŒ;
ãŸã èœã¡ãŠããïŒ ç¢ºãã«ãããã§ã¯äŸå€ã¯ãã§ã«ç°ãªã£ãŠãããããè峿·±ããã®ã§ããã
I / QtïŒqt start
05-17 11ïŒ12ïŒ33.975 11084-11084 /ãããžã§ã¯ãåA / libcïŒèŽåœçãªã·ã°ãã«11ïŒSIGSEGVïŒat 0x00000000ïŒã³ãŒã= 1ïŒãã¹ã¬ãã11084ïŒndroid.gribviewïŒ
05-17 11ïŒ12ïŒ33.978 11084-11084 /ãããžã§ã¯ãåA / libcïŒpidã«åæ¢ä¿¡å·ãéä¿¡ïŒ11084 in void debuggerd_signal_handlerïŒintãsiginfo_tãvoidïŒ
å°ãªããšãããªããèŠãããšãã§ããæãããããããŸãã ããã«qt startã§ãèå³ã®ããã¡ãœãããèŠã€ããŸãã
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { QT_USE_NAMESPACE typedef union { JNIEnv *nativeEnvironment; void *venv; } UnionJNIEnvToVoid; __android_log_print(ANDROID_LOG_INFO, "Qt", "qt start"); UnionJNIEnvToVoid uenv; uenv.venv = Q_NULLPTR; m_javaVM = Q_NULLPTR; if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "GetEnv failed"); return -1; } JNIEnv *env = uenv.nativeEnvironment; if (!registerNatives(env) || !QtAndroidInput::registerNatives(env) || !QtAndroidMenu::registerNatives(env) || !QtAndroidAccessibility::registerNatives(env) || !QtAndroidDialogHelpers::registerNatives(env)) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } m_javaVM = vm; return JNI_VERSION_1_4; }
ãã°ãã倿ãããšãregisterNativesã®1ã€ã«èœã¡ãã®ã§ãããã§ããïŒåregisterNativesã«ãã°ãç»é²ããŸããïŒã 圌ã¯èœã¡ã
registerNatives(env)
ããªãã¡ïŒ
jmethodID methodID; GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;"); __android_log_print(ANDROID_LOG_INFO, "Check Class 8", "activity "); jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID); __android_log_print(ANDROID_LOG_INFO, "Check Class 9 ", " methodID "); GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "classLoader", "()Ljava/lang/ClassLoader;"); __android_log_print(ANDROID_LOG_INFO, "Check Class 10", " classLoader "); if(activityObject!=nullptr) { __android_log_print(ANDROID_LOG_INFO, "No tull activityObject", " Not Null "); } if(methodID!=nullptr) { __android_log_print(ANDROID_LOG_INFO, "No tull methodID", " Not Null "); } m_classLoaderObject = env->NewGlobalRef(env->CallStaticObjectMethod(m_applicationClass, methodID)); if(m_classLoaderObject!=nullptr) { __android_log_print(ANDROID_LOG_INFO, "No tull m_classLoaderObject", " Not Null "); } clazz = env->GetObjectClass(m_classLoaderObject);
èœäžã¯æåŸã®è¡ã§çºçããŸããã classLoaderObjectã¯nullã§ããããšã倿ããŸããã ãŸããactivityObjectãnullã§ããããšãçºçããŸããã ããã£ã ãã®äžéãªãã©ã°ã€ã³ãããŒãããåã«ãJNIã®ã¢ã¯ãã£ããã£ãäœæããŠã¿ãŸãããã ãããè¡ãã«ã¯ãJavaã³ãŒãã§æ¬¡ã®è¡ãèšè¿°ããŸãã
QtNative.setActivity(this, null); QtNative.setClassLoader(getClassLoader());
å°ããªäœè«ã QtNativeã¯ã©ã¹ã¯ããããžã§ã¯ãã«æ¥ç¶ããjarãã¡ã€ã«ã«ãããŸãã ããã«ãããã¯éåžžã«è峿·±ãã¯ã©ã¹ã§ãã ã¡ãœããããããŸãïŒ
QtNative.loadBundledLibraries(); QtNative.loadQtLibraries();
å¿
èŠãªãã©ã°ã€ã³ãããŒãããå¿
èŠããããŸãã ä»ã®ãšããããããèŠããŠããã©ã°ã€ã³ãæåã§æ¥ç¶ããããšã«æ»ããŸãã QtNativeã®ã¡ãœããsetActivityããã³setClassLoaderãåŒã³åºããšã次ã®ããšãå®çŸã§ããŸãã
registerNatives(env)
ããããåŸ
ã¡äŒãã¯ãã§ã«QtAndroidInput :: registerNativesïŒenvïŒã«ãããŸããã keyDownã€ãã³ãã®é¢æ°ã·ã°ããã£ãäžèŽããŸããã§ããã åºæ¬çã«ããã©ã³ã以å€ã¯å¿
èŠãªãã®ã§ãã³ãŒãã®æ¬¡ã®ã»ã¯ã·ã§ã³ãã³ã¡ã³ãã¢ãŠãããŸããã
if (!registerNatives(env) ) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; }
ãã®ãã©ã°ã€ã³ã¯å®å
šã«ããŠã³ããŒããããããã§ãã ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããã©ã°ã€ã³ãããŒãããQApplicationãåŒã³åºããŠã
éåžžã«ããç¥ãããŠããäŸå€ããã£ããããŸãã
ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãQtãã©ãããã©ãŒã ãã©ã°ã€ã³ãAndroidããèŠã€ããããªãããããŒãã§ããªãã£ããããèµ·åã«å€±æããŸããã
ãŸããææŠ
QtNative.loadBundledLibraries(); QtNative.loadQtLibraries();
ãŸããåé¡ã解決ããŸããã§ããã ããã ããã£ã ç§ãã¡ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãäœæãããšããçš®é¡ã«ç»ããŸãã äŸå€ãšããŠãã¡ãœããããã°ããèŠã€ããŸãïŒ
static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv) {
ããã ãã®ã¡ãœãããã©ãããåŒã³åºãããæ¢ããŠããŸãïŒ
void QGuiApplicationPrivate::createPlatformIntegration() {
ã€ãŸãããã®ãã©ã°ã€ã³ãæ¢ãå ŽæãšããŠargcããã³argvãä»ããŠåŒæ°ãæž¡ãããšãã§ããŸãã ããã«äºçŽãå
¥ããŠãqtãããã¬ãŒã§androidã®ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããããšããŸããããargcãšargvã¯ããããçããã§ãã1ãšqtãåéããlibrary_ã®ååã§ããããã©ã°ã€ã³ã¯åéããŸããã argcãšargvã«é©åãªå€ãå²ãåœãŠãŠã¿ãŸãããã
char *SDKEnvironment::argv[] = {"-platform libplugins_platforms_android_libqtforandroid.so:plugins/platforms/android/libqtforandroid.so -platformpluginpath /data/app-lib/__jniLibs"};
ããããããŸããããŸããã§ããã
解決ç
æ£çŽãªãšãããç· ãåããè¿«ã£ãŠããŠãäœãã©ãã§æ©èœããªãã£ãããç ç©¶ããããã«-ç§ã«ã¯æéã®
åããããŸããã ç§ãå©ãã解決çã¯æ¬¡ã®ãšããã§ãã
- qtã§apkã§ã¯ãªããaarãäœæããŸãããã ãããè¡ãã«ã¯ãqt Creatorã«ç§»åããŠgradleãã¡ã€ã«ãèŠã€ãããã®äžã®
apply plugin: 'com.android.applicatioin'
è¡ã倿ŽããŠapply plugin: 'com.android.applicatioin'
ãapply plugin: 'com.android.library'
ã ãããã£ãŠãapkã§ã¯ãªãaarãã¡ã€ã«ãäœæããŸã - 次ã«ãAndroid Studioã®ã¢ããªã±ãŒã·ã§ã³ã«è¿œå ããŸãã New-> Moduleã«ç§»åããimport aarãéžæããã¢ãžã¥ãŒã«ãå³ã¯ãªãã¯ããŠOpen Module Settingsãéžæããdependencyã¿ãã«ç§»åããŠqtã¢ãžã¥ãŒã«ã«äŸåé¢ä¿ã远å ããŸãã
ãããããAndroidã¹ã¿ãžãªã«ããjniããã¹ãŠqtã«è»¢éããŸããã QApplicationãååºŠäœæããããšããŸããããããŸããããŸããã
ãŸãšã
ãã®åé¡ã解決ããå¥ã®æ¹æ³ããããšç¢ºä¿¡ããŠããŸãã ç§ãã©ããééãããã誰ããææããã°ãããã¯çŽ æŽãããããšã§ãã ã€ã³ã¿ãŒãããã§åé¡ã®è§£æ±ºçãèŠã€ããããªãã£ãã®ã§ãèªåã§è§£æ±ºçãæäŸããŸãã