Cc.loader.loadImg load online image cause app not responding until request sent

Hi,

I able to use cc.loader.loadImg to load online image and show with cc.Sprite.

However, when called cc.loader.loadImg, app will become unresponsive until the http request sent out.

The app pause longer when there are many online images to load at the same time.

Example :

for(int i=0; i<imageArray.length; i++)
{
    cc.loader.loadImg(imageArray[i], {isCrossOrigin : true}, callback);
}

If calling cc.loader.loadImg once caused app pause for 1 sec, this code will caused app pause for 5sec.

Is there anyway to handle cc.loader.loadImg in background or multi-thread?

Thanks!

I see the problem, in fact, the download process is asynchronous, but we requested the size of the file synchronously.

long contentSize = _downloader->getContentSize(_url);
if (contentSize == -1) {
    cocos2d::extension::Downloader::Error err;
    onError(err);
}
else {
    _size = contentSize / sizeof(unsigned char);
    _buffer = (unsigned char*)malloc(contentSize);
    _downloader->downloadToBufferAsync(_url, _buffer, _size);
}

I will find a solution to make it totally asynchronous. Thanks for reporting this

https://github.com/cocos2d/cocos2d-js/issues/1217

@pandamicro

Thanks for the help and information.

There is one more problem when calling cc.loader.loadImg with same online image url at the same time.

The app will crashed. Tested on cocos2d-js v3.1 and v3.2.

This problem not happen if run in browser mode.

I also believe making the main thread download the image makes Android crush, can you please check it as well?
Thanks.

How did you do exactly to download an image with the main thread ?

as far as I understand all actions are performed on the main thread.
Thus, when calling cc.loader.loadImg, the main thread is downloading the image.

Actually no, cc.loader.loadImg will call downloadToBufferAsync API in Downloader which download the image in another thread

alright.
but what’s the use of it, if you can’t actually use it?
I mean, everytime I’m trying to load an image I get an error:
Image from origin ‘’ has been blocked from loading by Cross-Origin Resource Sharing policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:63342’ is therefore not allowed access.

@shirkan

About No ‘Access-Control-Allow-Origin’, try check this post.

It should caused by the security policy of cross origin but not cocos2d-js engine.

so there is actually no way to show photos from other servers on Android and iOS platforms?
Sounds too weird…

@shirkan

If the photo of the server allow cross-origin resource sharing, then we can show the photos using same way.

So, the photos you showing are on the server you can control?

If yes, try search “enable cross-origin resource sharing” and edit the .htaccess to enable it.

If not, try using http://www.corsproxy.com/ as suggest on this post.
[SOLVED] Load external sprites from an URL

Thank you,
I already came across this post. The thing is it works on web only.
code:

var imageURL = "http://www.corsproxy.com/cdn.shephertz.com/repository/files/eb075343180ff254993d760eaeff219d9c6f3cd768c976f4cb7c25e6a6a7a88e/8e8984598d28645d304057d9a59cfd28e4648a60/ee227a6df135380c8bb1c4e9ad071c07e1fe284a.png"
cc.loader.loadImg(imageURL, {isCrossOrigin : true});

later on:

var sprite = new cc.Sprite(imageURL);

Errors on iOS & Android:

HTTP/1.1 400 Bad Request
Date: Wed, 31 Dec 2014 08:59:43 GMT
Connection: keep-alive
Server: Bogus
Content-Type: text/plain
Content-Length: 15
Via: 1.1 vegur

cocos2d: Get data from file(http://www.corsproxy.com/cdn.shephertz.com/repository/files/eb075343180ff254993d760eaeff219d9c6f3cd768c976f4cb7c25e6a6a7a88e/8e8984598d28645d304057d9a59cfd28e4648a60/ee227a6df135380c8bb1c4e9ad071c07e1fe284a.png) failed!

@shirkan

I tested with below code without using Corsproxy and it works properly.

You should try create the sprite with the callback of cc.loader.loadImg.

var self = this;

var imageURL = "http://cdn.shephertz.com/repository/files/eb075343180ff254993d760eaeff219d9c6f3cd768c976f4cb7c25e6a6a7a88e/8e8984598d28645d304057d9a59cfd28e4648a60/ee227a6df135380c8bb1c4e9ad071c07e1fe284a.png"
			
cc.loader.loadImg(imageURL, {isCrossOrigin : true}, function(err, texture)
{
	var spriteTest = new cc.Sprite(imageURL);
	spriteTest.setPosition((size.width*0.50), (size.height*0.50));
	self.addChild(spriteTest);
});

strange.
again it works ok on web, but iOS and Android fail with the following error:
Android

frameworks/js-bindings/cocos2d-x/../bindings/manual/ScriptingCore.cpp:1715: js_proxy_t *jsb_new_proxy(void *, JSObject *): assertion "! nativeObjjsObjtmp" failed'

iOS:

Assertion failed: (! nativeObjjsObjtmp), function jsb_new_proxy, file /Users/shirkan/GitHub/PiuPiu/frameworks/js-bindings/bindings/manual/ScriptingCore.cpp, line 1715.

What version of Cocos2d-js you using?

I using this on Cocos2d-js v3.1 and v3.2 without any problem.

ok I managed to get it to work on iOS.
The thing was I was calling this function twice (in a loop). When doing this only one time, it works ok.
So we are left with the problem when continuos calling this function.
Also, I wish I could retrieve a profile photo of a facebook user and download it.
It’s still tagged as a bug and I’m looking forward to see it solved.
Thanks!