gpt4 book ai didi

java - jni 回调中的黑色 Sprite

转载 作者:太空宇宙 更新时间:2023-11-04 13:38:52 25 4
gpt4 key购买 nike

我在 C++ 中制作了简单的辅助类来从 Android 调用 native 方法。

我的 C++ 函数:

extern "C"
{
JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_imagePicked(JNIEnv* env, jobject thiz, jstring filename);
};

JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_imagePicked(JNIEnv* env, jobject thiz, jstring filename){
std::string str = JniHelper::jstring2string(filename);
auto helper = NativeHelper::getInstance();
if(helper->imagePickedCallback != NULL){
helper->imagePickedCallback(str);
}
}

回调实现:

void HelloWorld::imagePicked(string filename){
CCLOG("image picked: %s", filename.c_str());
txtStatus->setString("Image picked: " + filename);
if(FileUtils::getInstance()->isFileExist(filename)){
auto sprite = Sprite::create(filename);
addChild(sprite);
sprite->setPosition(960 * rand_0_1(), 640 * rand_0_1());
sprite->setScale(0.1);
}
else{
CCLOG("File does not exist!");
}
}

它只是加载一个图像,将其缩放到 10% 并在屏幕上放置一个随机位置。我也可以看到 CCLOG。

最后java实现:

public static native void imagePicked(String filename);

public static void showImagePicker(){
_appActivity.runOnUiThread(new Runnable() {

@Override
public void run() {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
_appActivity.startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}

});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == SELECT_PHOTO){
if(resultCode == RESULT_OK){
Uri selectedImage = data.getData();
final String path = getRealPathFromURI(selectedImage);
Cocos2dxHelper.runOnGLThread(new Runnable() {

@Override
public void run() {
imagePicked(path);
}
});
}
}
}

之前我只是直接从uithread调用imagePicked,但是发现opengl不是线程安全的,应该在glthread上完成。

无论如何这样做都会调用回调, Sprite 在屏幕上的随机位置上以正确的大小出现,但它是纯黑色的。 Ui 文本也变成黑色(调用 setString 后)。我还进行了测试,并使用硬编码文件名从 HelloWorld::init 函数中调用了此方法,它可以正常工作(图像出现,文本也可以)。所以这绝对是线程的问题。但我正在使用 runOnGLThread,所以它应该可以工作。我还阅读了一些插件源代码(应用内购买),也是以同样的方式完成的。

我还在名为“performFunctionInCocosThread”的调度程序中找到了方法,但是我无法让它工作:

JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_imagePicked(JNIEnv* env, jobject thiz, jstring filename){
std::string str = JniHelper::jstring2string(filename);
auto helper = NativeHelper::getInstance();
if(helper->imagePickedCallback != NULL && helper->scheduler != NULL){
helper->scheduler->performFunctionInCocosThread([&](){
helper->imagePickedCallback(str);
});
}
}

(调度器由HelloWorld-getScheduler()设置,我也试过director->getScheduler())。它使用信号 11 使应用程序崩溃(直接调用 jni 时使用信号 6 - 没有 runOnGLThread)。

任何帮助将不胜感激,问候

最佳答案

Cocos2d-x 线程不完全是 GL 线程——至少据我所知在 Android 中是这样。例如,参见 this discussion Cocos2dx 作者之间。

为了您的目的,您可以摆脱 runOnGLThread 并通过此函数将线程移动到 C++ 端:

Director::getInstance()->getScheduler()->performFunctionInCocosThread(/*a function here*/)

关于java - jni 回调中的黑色 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28560060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com