Qt移动应用开发:QML与Java的交互
上一篇文章讲到了如何实现QML和C++的交互,QML和C++的交互方法有很多,它们分别为使用上下文变量、注册QML类以及注册QML单例。那么这一次我们要了解如何使QML和Java进行交互。这里主要讲的是在Android系统下的实现,不适用于桌面平台J2SE的JVM。
原创文章,反对未声明的引用。原博客地址:http://blog.csdn.net/gamesdev/article/details/37997555
Qt5中针对不同的平台适配并开发了不同的模块,比如说Qt Windows Extras、Qt Mac Extras、Qt X11 Extras、Qt Android Extras等。这里我们主要聚焦Qt Android Extras,教大家如何使用这个模块实现和Java的交互。
QtAndroid Extras模块包含了三个类以及一个命名空间。QAndroidActivityReceiver用来接收Android的Activity的结果的;QAndroidJniEnvironment用来访问JNI环境变量的;QtAndroidJniObject就对应dalvik虚拟机中的普通Java类。此外QtAndroid命名空间中有一些有用的全局函数来与Java代码进行交互,比如使用QtAndroid::androidActivity()来获得当前运行的Activity。
我的独立游戏《吃药了》是包含了移动广告的,移动广告商的SDK是一个jar包,似乎无法整合进入我的项目,但是好就好在有Qt Android Extras模块,我利用这个模块再加上QML和C++的交互,最终让整合得以实现。我是使用这样一套方法实现QML调用Java代码的:
在上一篇文章介绍的三种方法中,我选择了使用QML调用C++注册的单例函数这样的方法来实现调用C++代码,然后再通过QtAndroidJniObject::callMethod()来调用Java的本地方法。为了实现这样一个功能,除了在上篇文章介绍的注册QML单例之外,还必须在该函数中调用Android方法。下面是SDActivityDelegateSingleton类的实现:
SDActivityDelegateSingleton.h
01.
#ifndef ADSINGLETON_H
02.
#define ADSINGLETON_H
03.
04.
#include <QObject>
05.
06.
// Android:绑定SuperDoctorActivity,负责广告API的调用
07.
class
SDActivityDelegateSingleton:
public
QObject
08.
{
09.
Q_OBJECT
10.
public
:
11.
SDActivityDelegateSingleton( QObject* pParent = Q_NULLPTR ):
12.
QObject( pParent )
13.
{
14.
}
15.
16.
Q_INVOKABLE
void
call(
const
QString& methodName );
17.
};
18.
19.
#endif
// ADSINGLETON_H
SDActivityDelegateSingleton.cpp
1.
01.
#include
"SDActivityDelegateSingleton.h"
02.
#
if
defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
03.
#include <QtAndroid>
04.
05.
void
SDActivityDelegateSingleton::call(
const
QString& methodName )
06.
{
07.
const
QAndroidJniObject& activity = QtAndroid::androidActivity( );
08.
qDebug(
"method name is: %s"
, qPrintable( methodName ) );
09.
activity.callMethod<
void
>( qPrintable( methodName ) );
10.
}
11.
#
else
12.
void
SDActivityDelegateSingleton::call(
const
QString& methodName )
13.
{
14.
qDebug(
"the desktop does not implement calling method: %s"
,
15.
qPrintable( methodName ) );
16.
}
17.
#endif
然后在是SuperDoctorActivity.java:
01.
// SuperDoctorActivity.java 这个Java文件重写了Android的Activity
02.
03.
package
com.jcystudio.superdoctor;
04.
05.
import
android.os.Bundle;
06.
import
android.util.Log;
07.
import
android.widget.LinearLayout;
08.
import
android.widget.FrameLayout;
09.
import
android.view.Gravity;
10.
import
org.qtproject.qt5.android.bindings.QtActivity;
11.
……
12.
13.
public
class
SuperDoctorActivity
extends
QtActivity
14.
{
15.
@Override
16.
public
void
onCreate( Bundle savedInstanceState )
17.
{
18.
super
.onCreate(savedInstanceState);
19.
……
20.
SmartBannerManager.init(
this
);
21.
}
22.
23.
……
24.
25.
public
void
showSmartAD( )
26.
{
27.
SmartBannerManager.show(
this
);
28.
}
29.
}
这样,通过QML就可以调用Java代码了,调用方法是:
01.
……
02.
function prepare( )
03.
{
04.
SDActivity.call(
"showSmartAD"
);
// ←调用Java方法
05.
this
.focus =
true
;
// 获得按键焦点,可以使用按键控制
06.
Controller.clearBlocks( );
07.
Controller.setupGame( mode, difficulty, map, actions, colors );
08.
headerSprite.currentFrame =
2
;
// 小人指向平常的位置
09.
readyMask.visible =
true
;
10.
backgroundMusic.play( );
11.
}
12.
……
使用这样的方法可以调用第三方Jar包代码,我想调用so库的代码也是可以的。