mirror of https://github.com/axmolengine/axmol.git
Add a buffer queue for Android Downloader to prevent out of memory
When the AssetManagerEx start downloading, it used to create all the download tasks all at once. When the app has a large number of asset files, it is likely to crash due to out of memory when creating threads for each of the download tasks. This commit adds a buffer queue to the downloader to use the `countOfMaxProcessingTasks` property from hints, preventing all the tasks from starting all at once.
This commit is contained in:
parent
6db6e596bb
commit
d174a98afa
|
@ -70,7 +70,7 @@ namespace cocos2d { namespace network {
|
|||
if (JniHelper::getStaticMethodInfo(methodInfo,
|
||||
JCLS_DOWNLOADER,
|
||||
"createDownloader",
|
||||
"(II" JARG_STR ")" JARG_DOWNLOADER))
|
||||
"(II" JARG_STR "I)" JARG_DOWNLOADER))
|
||||
{
|
||||
jobject jStr = methodInfo.env->NewStringUTF(hints.tempFileNameSuffix.c_str());
|
||||
jobject jObj = methodInfo.env->CallStaticObjectMethod(
|
||||
|
@ -78,7 +78,8 @@ namespace cocos2d { namespace network {
|
|||
methodInfo.methodID,
|
||||
_id,
|
||||
hints.timeoutInSeconds,
|
||||
jStr
|
||||
jStr,
|
||||
hints.countOfMaxProcessingTasks
|
||||
);
|
||||
_impl = methodInfo.env->NewGlobalRef(jObj);
|
||||
DLLOG("android downloader: jObj: %p, _impl: %p", jObj, _impl);
|
||||
|
|
|
@ -99,6 +99,10 @@ class FileTaskHandler extends FileAsyncHttpResponseHandler {
|
|||
@Override
|
||||
public void onFinish() {
|
||||
// onFinish called after onSuccess/onFailure
|
||||
Runnable taskRunnable = _downloader.dequeue();
|
||||
if (taskRunnable != null) {
|
||||
Cocos2dxHelper.getActivity().runOnUiThread(taskRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -166,7 +170,9 @@ public class Cocos2dxDownloader {
|
|||
private int _id;
|
||||
private AsyncHttpClient _httpClient = new AsyncHttpClient();
|
||||
private String _tempFileNameSufix;
|
||||
private int _countOfMaxProcessingTasks;
|
||||
private HashMap _taskMap = new HashMap();
|
||||
private Queue<Runnable> _taskQueue = new LinkedList<Runnable>();
|
||||
|
||||
void onProgress(final int id, final long downloadBytes, final long downloadNow, final long downloadTotal) {
|
||||
DownloadTask task = (DownloadTask)_taskMap.get(id);
|
||||
|
@ -202,7 +208,7 @@ public class Cocos2dxDownloader {
|
|||
});
|
||||
}
|
||||
|
||||
public static Cocos2dxDownloader createDownloader(int id, int timeoutInSeconds, String tempFileNameSufix) {
|
||||
public static Cocos2dxDownloader createDownloader(int id, int timeoutInSeconds, String tempFileNameSufix, int countOfMaxProcessingTasks) {
|
||||
Cocos2dxDownloader downloader = new Cocos2dxDownloader();
|
||||
downloader._id = id;
|
||||
|
||||
|
@ -214,6 +220,7 @@ public class Cocos2dxDownloader {
|
|||
downloader._httpClient.allowRetryExceptionClass(javax.net.ssl.SSLException.class);
|
||||
|
||||
downloader._tempFileNameSufix = tempFileNameSufix;
|
||||
downloader._countOfMaxProcessingTasks = countOfMaxProcessingTasks;
|
||||
return downloader;
|
||||
}
|
||||
|
||||
|
@ -222,7 +229,7 @@ public class Cocos2dxDownloader {
|
|||
final String url = url_;
|
||||
final String path = path_;
|
||||
|
||||
Cocos2dxHelper.getActivity().runOnUiThread(new Runnable() {
|
||||
Runnable taskRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DownloadTask task = new DownloadTask();
|
||||
|
@ -269,7 +276,13 @@ public class Cocos2dxDownloader {
|
|||
downloader._taskMap.put(id, task);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
if (downloader._taskQueue.size() < downloader._countOfMaxProcessingTasks) {
|
||||
Cocos2dxHelper.getActivity().runOnUiThread(taskRunnable);
|
||||
downloader._taskQueue.add(null);
|
||||
} else {
|
||||
downloader._taskQueue.add(taskRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
public static void cancelAllRequests(final Cocos2dxDownloader downloader) {
|
||||
|
@ -291,6 +304,16 @@ public class Cocos2dxDownloader {
|
|||
});
|
||||
}
|
||||
|
||||
public Runnable dequeue() {
|
||||
if (!_taskQueue.isEmpty() && _taskQueue.element() == null) {
|
||||
_taskQueue.remove();
|
||||
}
|
||||
if (!_taskQueue.isEmpty()) {
|
||||
return _taskQueue.remove();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
native void nativeOnProgress(int id, int taskId, long dl, long dlnow, long dltotal);
|
||||
native void nativeOnFinish(int id, int taskId, int errCode, String errStr, final byte[] data);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue