您的位置:首页 > 移动开发 > Android开发

QT, THE BETTER ANDROID NDK:Android Studio调用Qt编写的so库

2017-04-28 23:32 531 查看
本文翻译:QT, THE BETTER ANDROID NDK点击打开链接

要点:怎么在Android Studio中调用qt编写的so库, 同时怎么去加载相关的qt动态库。

一.QT for Android编译so库

创建Qt Widgets Application ->构建套件选Android, 删除原来的Widget和main;(原文要求创建库工程,但是我最后测试和作者后面的的操作有冲突,需要创建app应用)

pro文件:


QT       += core gui
QT += widgets

TARGET = untitled3
TEMPLATE = app

DEFINES += UNTITLED3_LIBRARY

SOURCES += untitled3.cpp

HEADERS += untitled3.h\
untitled3_global.h

unix {
target.path = /usr/lib
INSTALLS += target
}


untitled3_global.h:

#ifndef UNTITLED3_GLOBAL_H
#define UNTITLED3_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(UNTITLED3_LIBRARY)
# define UNTITLED3SHARED_EXPORT Q_DECL_EXPORT
#else
# define UNTITLED3SHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // UNTITLED3_GLOBAL_H

untiled3.h:


#ifndef UNTITLED3_H
#define UNTITLED3_H

#include "untitled3_global.h"
#include <jni.h>

class UNTITLED3SHARED_EXPORT Untitled3
{

public:
Untitled3();

};

#ifdef __cplusplus
extern "C"
{
#endif

JNIEXPORT void JNICALL Java_eu_microscopictopic_scratchclib_JavaNatives_sendIntToClib(JNIEnv * env, jobject thisObj, jint n);

#ifdef __cplusplus
}
#endif

#endif // UNTITLED3_H



untiled3.cpp:

#include "untitled3.h"
#include "jni.h"
#include "android/log.h"

Untitled3::Untitled3()
{
}

JNIEXPORT void JNICALL
Java_eu_microscopictopic_scratchclib_JavaNatives_sendIntToClib(JNIEnv * env, jobject thisObj, jint n)
{
__android_log_print(ANDROID_LOG_INFO, "Scratch_c_lib", "Are you kidding me? receiveToClib:%d", n);
}


构建目录放在Android studio中,这个在第二步说

二.构建Android Studio工程

按照Android Studio正常模式创建(为了和qt工程中jni接口保持一致,包名为:eu.microscopictopic.scratchclib),在app/src/目录下创建qtgen目录,第一步的qt工程构建目录设置为此目录。



App/build.gradle 

Android中加入:

sourceSets {
main {
java.srcDirs = ['/src/main/java']
res.srcDirs = ['src/main/res','src/qtgen/android-build/res']
jniLibs.srcDirs = ['src/qtgen/android-build/libs']
}
}
设置qt库目录和布局目录
dependencies中加入:
compile files('src/qtgen/android-build/libs/QtAndroid-bundled.jar')
加入qt-builded jar编译
qt工程编译后,在qtgen/android-build/res/valuse/libs.xml文件中可知:
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
<item>https://download.qt.io/ministro/android/qt5/qt-5.7</item>
</array>

<!-- The following is handled automatically by the deployment tool. It should
not be edited manually. -->

<array name="bundled_libs">

</array>

<array name="qt_libs">
<item>gnustl_shared</item>
<item>Qt5Core</item>
<item>Qt5Gui</item>
<item>Qt5Widgets</item>

</array>

<array name="bundled_in_lib">
<item>libplugins_platforms_android_libqtforandroid.so:plugins/platforms/android/libqtforandroid.so</item>
<item>libplugins_platforms_libqminimal.so:plugins/platforms/libqminimal.so</item>
<item>libplugins_platforms_libqoffscreen.so:plugins/platforms/libqoffscreen.so</item>
<item>libplugins_generic_libqevdevkeyboardplugin.so:plugins/generic/libqevdevkeyboardplugin.so</item>
<item>libplugins_generic_libqevdevmouseplugin.so:plugins/generic/libqevdevmouseplugin.so</item>
<item>libplugins_generic_libqevdevtabletplugin.so:plugins/generic/libqevdevtabletplugin.so</item>
<item>libplugins_generic_libqevdevtouchplugin.so:plugins/generic/libqevdevtouchplugin.so</item>
<item>libplugins_imageformats_libqdds.so:plugins/imageformats/libqdds.so</item>
<item>libplugins_imageformats_libqgif.so:plugins/imageformats/libqgif.so</item>
<item>libplugins_imageformats_libqicns.so:plugins/imageformats/libqicns.so</item>
<item>libplugins_imageformats_libqico.so:plugins/imageformats/libqico.so</item>
<item>libplugins_imageformats_libqjpeg.so:plugins/imageformats/libqjpeg.so</item>
<item>libplugins_imageformats_libqtga.so:plugins/imageformats/libqtga.so</item>
<item>libplugins_imageformats_libqtiff.so:plugins/imageformats/libqtiff.so</item>
<item>libplugins_imageformats_libqwbmp.so:plugins/imageformats/libqwbmp.so</item>
<item>libplugins_imageformats_libqwebp.so:plugins/imageformats/libqwebp.so</item>

</array>
<array name="bundled_in_assets">

</array>

</resources>

此处,qt生成的xml文件已经定义好了 要加载的库文件:
平台库:libqtforandroid.so
图片,Gui,Core,Widget等,在qtgen/android-build/libs目录下可以找到
要加载的库我们知道了,现在在java中怎么去加载这些库文件:
package eu.microscopictopic.scratchclib;

import 	android.content.Context;
import 	android.util.Log;

public class JavaNatives {

public static native void sendIntToClib(int n);

public static void init(Context context) {
load(context, R.array.bundled_in_assets);
load(context, R.array.qt_libs);
System.loadLibrary("untitled3");
//这一步虽然保报错了,但是senderIntToClib方法还是调用成功。
// W/linker: libuntitled3.so: unused DT entry: type 0x6ffffffe arg 0x3cc
// W/linker: libuntitled3.so: unused DT entry: type 0x6fffffff arg 0x1
}

static void load(Context context, int arrayResourceId) {
String[] libsToLoad = context.getResources().getStringArray(arrayResourceId);
for (String lib : libsToLoad) {
if (lib.indexOf('/')>-1) {
lib=lib.substring(lib.indexOf('/'));
}
if (lib.indexOf("lib")==0) {
lib=lib.substring(3);
}
if (lib.endsWith(".so")) {
lib=lib.substring(0, lib.length()-3);
}
Log.i(JavaNatives.class.getSimpleName(), "loading "+lib);
try {
System.loadLibrary(lib);
} catch (Throwable e) {
Log.i(JavaNatives.class.getSimpleName(), "failed to load "+lib+" "+e);
e.printStackTrace();
}
Log.i(JavaNatives.class.getSimpleName(), "Successfully loaded "+lib);
}
}
}

在Activity中怎么使用?这里依赖QtAndroid-bundled.jar,我们右键-Add as library-app...:
java目录:
使用:
package com.kdab.training;

import android.os.Bundle;
import org.qtproject.qt5.android.bindings.QtActivity;
import eu.microscopictopic.scratchclib.JavaNatives;

public class MyActivity extends QtActivity {
public static MyActivity s_activity = null;

@Override
public void  onCreate(Bundle savedInstanceState)
{
//JavaNatives.init(getApplicationContext());
JavaNatives.sendIntToClib(222);

s_activity = this;
super.onCreate(savedInstanceState);

}

@Override
protected void onDestroy()
{
super.onDestroy();
s_activity = null;
}
}

这样就可以编写qt android动态库给Android Studio调用了,但是经过我测试,窗体类是无法使用的,具体用途没有实验。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt ndk Android Studio So库