Dan*_*y19 7 c++ java java-native-interface qt signals-slots
我有一个Android应用程序,可以获取未读的Facebook通知和收件箱.应用程序必须在QT中完成,但我几乎不了解QT C++,因此我在java中开发了应用程序,并使用JNI从QT调用java类.这工作正常,但问题是我每次有新的Facebook通知/消息时都需要发送一个插槽(在QT端).
所以我的问题是:每分钟,如何从Java通知QT我有新消息并发送字符串?
这是我的java代码:
主类:
public class MainActivity extends FragmentActivity {
...
static public void startFacebookActivity() {
String msgTag = "FACEBOOK_APP";
try {
Activity mother = QtNative.activity();
Intent intent = new Intent(mother, MainActivity.class);
mother.startActivity(intent);
} catch (Exception e) {
Log.e(msgTag, e.toString());
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
FRAGMENT CLASS(每分钟验证是否有新的facebook消息,如果是,则假设通知QT并发送消息,以便QT能够发送一个插槽)
private static native void publishNotification(String notification);
....
if (newNotification==true)
publishNotification(responseNotification);
...
Run Code Online (Sandbox Code Playgroud)
QT方面
facebookAndroid.cpp
#include "facebookAndroid.h"
#include <QtAndroidExtras>
FacebookAndroid* FacebookAndroid::s_instance = 0;
FacebookAndroid::FacebookAndroid(QObject *parent) : QObject(parent) { s_instance = this;}
void FacebookAndroid::startAndroidFacebook() {
QAndroidJniObject::callStaticMethod<void>("org.qtproject.example.MainActivity",
"startFacebookActivity",
"()V");
}
FacebookAndroid* FacebookAndroid::instance() {
return s_instance;
}
static void publishNotification(JNIEnv *env, jclass /*clazz*/, jstring notification) {
const char* nativeString = env->GetStringUTFChars(notification, 0);
FacebookAndroid::instance()->handleNewNotification(QString(nativeString));
}
static JNINativeMethod methods[] = {
{"publishNotification", "(Ljava/lang/String;)V", (void *)publishNotification}
};
jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4) != JNI_OK)
return JNI_FALSE;
jclass clazz = env->FindClass("org/qtproject/example/MainActivity");
if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)
return JNI_FALSE;
return JNI_VERSION_1_4;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QtQuick>
#include "facebookAndroid.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
FacebookAndroid sa(&viewer);
viewer.rootContext()->setContextProperty(QString("iniciaFacebook"), &sa);
viewer.setMainQmlFile(QStringLiteral("qml/FacebookTry/main.qml"));
viewer.showExpanded();
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)
facebookAndroid.h
#ifndef FACEBOOKANDROID_H
#define FACEBOOKANDROID_H
#include <QObject>
#include <jni.h>
class FacebookAndroid : public QObject {
Q_OBJECT
public:
FacebookAndroid(QObject *parent = 0);
FacebookAndroid* instance();
void handleNewNotification(QString notification);
protected:
static FacebookAndroid *s_instance;
public slots:
void startAndroidFacebook();
};
#endif // FACEBOOKANDROID_H
Run Code Online (Sandbox Code Playgroud)
建筑时的错误
In function 'void publisNotification(JNIEnv*, jclass,jstring)'
cannot call member function 'FacebookAnddroid::instance()' without object
FacebookAndroid::instance()->handleNewNotification(QString(nativeString));
in facebookAndroid.cpp
Run Code Online (Sandbox Code Playgroud)
每一个帮助都会非常有帮助
如果我不这样做,我可能会选择这条路:
在你的 Java 类中:
class Main Activity {
// ...
private static native void publishNotification(String notification);
// Call it from your Java code as it has a proper implementation
//...
if (newNotification) {
publishNotification(notification);
}
//...
Run Code Online (Sandbox Code Playgroud)
在 C++/Qt 方面:
单例实现:
//in facebookandroid.h
class FacebookAndroid {
public:
FacebookAndroid* instance();
void handleNewNotification(QString notification);
protected:
static FacebookAndroid *s_instance;
};
//in facebookandroid.cpp
FacebookAndroid* FacebookAndroid::s_instance = 0;
FacebookAndroid::FacebookAndroid(QObject *parent) : QObject(parent) {
s_instance = this; // remind your first instanciation here
}
FacebookAndroid* FacebookAndroid::instance() {
return s_instance;
}
Run Code Online (Sandbox Code Playgroud)
原生方法实现:
//In facebookandroid.cpp
static void publishNotifcation(JNIEnv *env, jclass /*clazz*/, jstring notification) {
const char* nativeString = env->GetStringUTFChars(notification, 0);
FacebookAndroid::instance()->handleNewNotification(QString(nativeString));
}
Run Code Online (Sandbox Code Playgroud)
由于我们只能通过静态方法来做到这一点,因此我必须在类中定义一个单例来仅访问一个特定的实例。
方法注册:
//In facebookandroid.cpp
static JNINativeMethod methods[] = {
{"publishNotification", "(Ljava/lang/String;)V", (void *)publishNotification}
};
jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4) != JNI_OK)
return JNI_FALSE;
jclass clazz = env->FindClass("org/qtproject/example/MainActivity");
if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)
return JNI_FALSE;
return JNI_VERSION_1_4;
}
Run Code Online (Sandbox Code Playgroud)
经过一番研究,我发现了一个特别有用且完整的示例。它的目的是实现应用内购买,但机制与我在这个答案中描述的完全相同。
| 归档时间: |
|
| 查看次数: |
4572 次 |
| 最近记录: |