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

本文翻译: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调用了,但是经过我测试,窗体类是无法使用的,具体用途没有实验。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值