是否可以使用NDK创建UI元素? - Android文档中缺少规范

时间:2012-10-10 14:46:34

标签: android user-interface android-ndk native native-activity

在阅读相关文档之后,如果只使用NDK编译的C ++ / C代码,我就可以创建用于获取用户输入的按钮或其他UI元素之类的内容。

当我想要处理需要保持关注的“窗口”或活动时没有问题,但我不知道如何使用回调和用户输入的元素构建UI。

奇怪的是,有一个窗口框架,但没有任何UI元素回调的痕迹。

我可以使用NDK构建触摸按钮或虚拟游戏手柄吗?


我很欣赏我们的努力和事实,我们越来越接近我的观点,但显然我并没有给自己解释得足够好。

我找到了这张图片here enter image description here

现在我的问题和这个问题的焦点是:

假设我可以放置并绘制这个虚拟操纵杆,我如何只能检测到这些动作,并使用Android进行回调,例如Joystick.onUpJoystick.onDown并仅使用NDK?

如果NDK没有这种回调,我应该每次检测[x,y]位置,将其与我操纵杆的位置进行比较,存储前一个位置,比较之前的位置和下一个得到方向?

由于传感器以非常快的速度抛出事件,我认为仅考虑原始的X,Y耦合,我自己构建这个,最终将会有一个非常低效的控制系统,因为它不会在操作系统级别进行优化使用适当的传感器调用。

根据NativeActivity示例,还不清楚如何处理多个触摸点,例如我如何同时处理2个触摸事件?

只需考虑上面的图像,并考虑只有1个触点的x,y坐标,以及如何以NDK支持的有效方式解决这个问题。

感谢。

2 个答案:

答案 0 :(得分:10)

当然可以。阅读从C(++)调用Java,并调用相应的Java函数 - 逐个构造UI元素(布局,按钮等),或加载XML布局。没有特定于C的接口,但Java可以调用它。

除非是游戏,否则你打算通过OpenGL ES自己绘图。我不确定你是否可以混搭。

NativeActivity中,您仍然可以获得指向Java Activity对象的指针并调用其方法 - 它是clazz结构的ANativeActivity成员,它传递给您的{{1}通过android_main结构作为参数。拿起那个指针,从中取出android_app,并指定一个布局。

这与OpenGL绘图如何互操作,我不确定。

编辑:关于整理自己的输入处理。关键回调是JNIEnv*结构中的onInputEvent(struct android_app* app, AInputEvent* event)。将回调放在那里,Android会在适当的时候调用它。使用android_app检索事件类型;触摸事件的类型为AINPUT_EVENT_TYPE_MOTION。

EDIT2:这是抓取触摸事件的最小原生应用程序:

AInputEvent_getType(event)

当然,您需要在其周围添加一个项目,包括清单,Android.mk和所有内容。 Android.mk将需要以下作为最后一行:

#include <jni.h>
#include <android_native_app_glue.h>
#include <android/log.h>

static int32_t OnInput(struct android_app* app, AInputEvent* event)
{
    __android_log_write(ANDROID_LOG_ERROR, "MyNativeProject", "Hello input event!");
    return 0;
}

extern "C" void android_main(struct android_app* App)
{
    app_dummy();
    App->onInputEvent = OnInput;

    for(;;)
    {
         struct android_poll_source* source;
         int ident;
         int events;

         while ((ident = ALooper_pollAll(-1, NULL, &events, (void**)&source)) >= 0)
         {
             if(source != NULL)
                 source->process(App, source);

             if (App->destroyRequested != 0)
                     return;
         }
    }

}

$(call import-module,android/native_app_glue) 是一个静态库,为通常通过Java使用的API提供一些C桥接。

你也可以在没有胶水库的情况下做到这一点。但是你需要提供自己的函数native_app_glue和其他一些回调函数。 ANativeActivity_onCreate / android_main组合是由胶水库定义的接口。

编辑:对于触摸坐标,使用android_app,将事件对象作为第一个参数传递,将指针的索引作为第二个参数传递。使用AMotionEvent_getX/Y()检索指针数(触摸点)。这是您对多点触控事件的原生处理。

  

我应该每次检测[x,y]位置,将其与之比较   我的操纵杆的位置,存储以前的位置,比较   前一个位置和下一个位置得到方向?

简而言之,是的,你是。虚拟操纵杆没有内置平台支持;你处理触摸和坐标,并将其转换为你的应用程序的UI比喻。这几乎是编程的本质。

不是“每次都” - 只有在它改变的时候。 Android是一个事件驱动的系统。

现在,关于你的“我希望它在操作系统级”的情绪。这在许多层面都是错误的。首先,操作系统不欠你任何东西。操作系统就是这样,接受或离开它。其次,不愿意扩展努力(AKA懒惰)在软件社区中通常是不受欢迎的。第三,OS代码仍然是代码。将某些内容移入操作系统可能会获得一些效率,但为什么您认为它会使用户产生明显的差异?这是我们谈论的触摸处理 - 不是特别CPU密集型任务。你真的构建了一个应用程序,个人资料并找不到它的表现吗?在你做之前,不要猜测瓶颈会在哪里。这个词就是“过早优化”,这是每个人和他们叔叔的猫会警告你的东西。

答案 1 :(得分:0)

Rawdrawandroid 显示没有什么是不可能的。使用它,您可以完全用 C/C++ 编写 UI 和处理 UI 事件。

注意:不会使用java、classes.dex、字节码。

示例应用:https://play.google.com/store/apps/details?id=org.cnlohr.colorchord

请阅读 rawdraw 开发人员如何解决常见情况:

使用此框架,您可以获得:

<块引用>
  • 制作一个支持 OpenGL ES 的窗口
  • 加速度计/陀螺仪输入,多点触控
  • 用于按键输入的安卓键盘
  • 能够在您的 APK 中存储资产文件并使用 AAssetManager 读取它们
  • 使用声音等内容的权限支持。 https://github.com/cnlohr/cnfa
  • 中的示例
  • 直接访问 USB 设备。 https://github.com/cnlohr/androidusbtest
  • 中的示例

NDK UI 可以用 Java 以外的语言编写。

<块引用>

这也需要做一点,以便将它粘贴到互联网上所有那些在 Stack Overflow 上发布“那是不可能的”或“你做错了”的 Luddites 问题......请求 JNI 中的权限“哦,你必须在 Java 中做到这一点”或其他类似的愚蠢的东西。我对你对什么是可能的或什么是不可能的看法完全不感兴趣。这是计算机科学。没有限制。我可以为所欲为。这只是点点滴滴。你不拥有我。

你从C访问android api,就像java一样:

<块引用>

附言如果你想要一堆关于如何在 Android 上用 C 做大量你“需要”java 的事情的例子,滚动到这个文件的底部:https://github.com/cntools/rawdraw/blob/master/CNFGEGLDriver.c - 它展示了如何使用 JNI 来编组无需跳回 Java/Kotlin 领域,即可从 Android API 获取大量内容。