我正在研究涉及大量并发编程的Android项目,我将实现一些自定义的线程间通信(java.util.concurent中的那个不适合我的目的).
并发编程一般不容易,但对Dalvik来说似乎更难.要获得正确的代码,您应该了解一些具体的事情以及Dalvik出现问题的地方.我找不到关于Dalvik VM的详细文档.大多数Android资源(甚至developer.android.com专注于平台API,并没有提供任何关于一些非平凡(或低级)事物的深层信息).
例如,Dalvik VM遵循哪个版本的Java语言规范?根据答案,volatile变量的处理是不同的,并影响使用volatile变量的任何并发代码.
已经有一些相关问题:
而fadden的一些答案非常有用,但我仍然希望对所讨论的问题有更详细和完整的理解.
所以在我感兴趣的原始问题之下(如果有必要,我将更新列表,因为之前的问题的答案将到达):
volatile变量语义的支持有多完整?在Android中的双重检查锁定中,fadden提供以下注释:
对.通过添加"volatile"关键字,这将适用于单处理器(所有Android版本)和SMP(3.0"蜂窝"及更高版本)
这是否意味着拥有双核CPU但只有Android 2.3的三星Galaxy SII可能会错误地执行并发代码?(当然Galaxy只是一个例子,关于任何具有Android 3.0前平台的多核设备的问题)
在Is Dalvik的内存模型中与Java相同吗?该法登提供下列句子的答案:
目前没有发布的Dalvik版本与JSR-133完全正确
这是否意味着任何现有的正确并发Java代码在发布此评论的任何Android版本上可能无法正常工作?
@gnat发表评论:
@Alexey Dalvik不符合任何JLS版本,因为一致性要求通过JCK,这不是Dalvik的选项.这是否意味着您甚至无法应用标准Java编译器,因为它符合标准规范?那有关系吗?如果有,怎么样?
好吧,我的问题有些含糊不清.我实际上的意思是JLS不仅是Java编译器实现的规则,而且是任何JVM实现的隐含指南.实际上,例如,JLS声明某些类型的读写是原子操作.编译器编写器不是很有趣,因为读/写只是转换成单个操作码.但是对于任何应该正确实现这些操作码的JVM实现来说都是必不可少的.现在你应该看看我在说什么.虽然Dalvik接受并执行使用标准Java编译器编译的程序,但没有任何保证 …
虽然有许多关于在Android上使用OpenGL ES的样本,但在EGL的初始化/终止方面,所有这些似乎都是不正确的(甚至是Android SDK/NDK附带的).问题的根源在于Android应用程序模型,它正确地使用了EGL怪异的东西.
在所有Android样本甚至GLSurfaceView(实际上大多数样本只使用它)中,EGL初始化每个操作系统进程的真正问题涉及每个组件(Activity或WallpaperService)的EGL初始化/终止.这是完全错误的,因为所有组件都在同一个进程中运行!如果应用程序只包含一个组件,则没有问题,但如果应用程序中有多个组件且每个组件都使用OpenGL ES,则会出现问题.
只考虑使用OpenGL ES的两个应用程序组件同时运行并且其中一个组件完成的情况.完成这样的组件将调用eglTerminate()(在GLSurfaceView源代码中查看我正在谈论的内容),这将终止整个过程的EGL !从这一刻开始,来自另一个已在运行的组件的任何EGL调用都将失败!
我检查了大量的示例,并且所有示例都初始化并终止每个组件的EGL(实际上没有人看到我做过与GLSurfaceView不同的事情,其中大多数只是GLSurfaceView内部的副本).
而现在我很有兴趣找到一种"正确"的方式来使用EGL在Android上工作(关于初始化/终止).
"适当"的方式应该提供:
请注意,当没有使用EGL/OpenGL ES的活动实体时,(2)对于最小化应用程序的系统资源使用至关重要.
有任何想法吗?或许我忽略了Android上的EGL?
还有一个有趣的相关问题:
由于每个线程只允许一个活动渲染上下文,因此同一时间只有一个Component可以正常使用主线程中的OpenGL ES.在同一时间运行的主线程中有多个使用OpenGL ES的组件会导致问题,因为最后一个组件调用eglMakeCurrent()会隐藏"替换"所有其他组件的上下文(这实际上将完全打破组件逻辑).
据透露(感谢Romain Guy)Android实际上有一个内部解决方案,用于EGL初始化/终止问题,以明确的形式(它违反EGL规范,在Android文档中没有提到)"引用计数"在eglInitialize内部( )和eglTerminate().
我们正在开发我们的第一个Qt/QML应用程序(尝试技术).虽然技术看起来很有前景,但我们面临着许多意想不到的奇怪问题,这些问题在一开始就几乎放弃了.
这里有一个这样的问题.
我们希望应用程序具有以下文件夹布局:
--> ApplicationFolder
|--> qml // QML files (also structured by subfolders)
|--> resources // Application resources (images, sounds, data-files, etc.)
| |--> images // Image resources (also structured by subfolders)
| |--> data // Different data files
| |--> ... // Other resources
|--> Application.exe // Application executable
|--> *.dll // DLLs application depends on
Run Code Online (Sandbox Code Playgroud)
问题是,为了指定ImageQML项目的图像文件,我们必须使用相对于QML文件的路径?!这绝对是疯了.在开发过程中,文件有时会在文件夹之间移动(你移动QML文件并且必须修复它拥有的所有路径?!); 一些不同的QML文件必须引用相同的图像(相同的图像资源,但不同的QML文件中的实际路径不同).
所以问题是:如何指定相对于应用程序文件夹的图像路径?有可能吗?
提前致谢!
PS.在我们的案例中,使用Qt的资源系统(当资源嵌入到可执行文件中时)不是一个选项.我们需要磁盘上的原始资源(包括QML文件本身,至少在开发阶段).
PPS.在花了一整天的时间通过文档/ google/stackoverflow解决了这个问题后写了这个问题; 根本没有成功(大多数示例使用资源嵌入,其他示例太简单,只使用相对路径).
我注意到Android NDK(在我的情况下是r6b)产生了不合理的大结果.so文件.例如,在我的情况下,我有大约150-200行C++代码(6个本机方法和3个C++最简单的类),这个本机代码生成60kb(!). so,启用异常和RTTI或12kb .so,禁用异常和RTTI.只是为了检查我已经编译了包含在NDK包中的hello-jni示例,并从此示例获得10kb .so用于单行本机方法.
在我看来,对于移动平台而言,这在某种程度上是不合理的开销(在我的桌面上,通过大小代码产生的可比性小约10-15倍.so).
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0xc18
Start of program headers: 52 (bytes into file)
Start of section headers: 9344 (bytes into …Run Code Online (Sandbox Code Playgroud)