mirror of https://github.com/axmolengine/axmol.git
CCDownloader-android implements File Task Download.
This commit is contained in:
parent
9b4fe5b5a1
commit
7e2fe05050
|
@ -21,30 +21,218 @@
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <unordered_map> // temp
|
|
||||||
#include "network/CCDownloader-android.h"
|
#include "network/CCDownloader-android.h"
|
||||||
|
|
||||||
#include "network/CCDownloader.h"
|
#include "network/CCDownloader.h"
|
||||||
|
#include "platform/android/jni/JniHelper.h"
|
||||||
|
|
||||||
namespace cocos2d {
|
#define JCLS_DOWNLOADER "org/cocos2dx/lib/Cocos2dxDownloader"
|
||||||
using namespace std;
|
#define JCLS_TASK "com/loopj/android/http/RequestHandle"
|
||||||
|
#define JARG_STR "Ljava/lang/String;"
|
||||||
|
#define JARG_DOWNLOADER "L" JCLS_DOWNLOADER ";"
|
||||||
|
#define JARG_TASK "L" JCLS_TASK ";"
|
||||||
|
|
||||||
namespace network {
|
using namespace std;
|
||||||
|
|
||||||
|
static bool _registerNativeMethods(JNIEnv* env);
|
||||||
|
|
||||||
|
unordered_map<int, cocos2d::network::DownloaderAndroid*> sDownloaderMap;
|
||||||
|
|
||||||
|
namespace cocos2d { namespace network {
|
||||||
|
|
||||||
|
static int sTaskCounter;
|
||||||
|
static int sDownloaderCounter;
|
||||||
|
|
||||||
|
struct DownloadTaskAndroid : public IDownloadTask
|
||||||
|
{
|
||||||
|
DownloadTaskAndroid()
|
||||||
|
:id(++sTaskCounter)
|
||||||
|
{
|
||||||
|
DLLOG("Construct DownloadTaskAndroid: %p", this);
|
||||||
|
}
|
||||||
|
virtual ~DownloadTaskAndroid()
|
||||||
|
{
|
||||||
|
|
||||||
|
DLLOG("Destruct DownloadTaskAndroid: %p", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int id;
|
||||||
|
shared_ptr<const DownloadTask> task; // reference to DownloadTask, when task finish, release
|
||||||
|
};
|
||||||
|
|
||||||
DownloaderAndroid::DownloaderAndroid(const DownloaderHints& hints)
|
DownloaderAndroid::DownloaderAndroid(const DownloaderHints& hints)
|
||||||
|
: _id(++sDownloaderCounter)
|
||||||
|
, _impl(nullptr)
|
||||||
{
|
{
|
||||||
|
// use local static variable make sure native methods registered once
|
||||||
|
static bool _registered = _registerNativeMethods(JniHelper::getEnv());
|
||||||
|
DLLOG("Construct DownloaderAndroid: %p", this);
|
||||||
|
JniMethodInfo methodInfo;
|
||||||
|
if (JniHelper::getStaticMethodInfo(methodInfo,
|
||||||
|
JCLS_DOWNLOADER,
|
||||||
|
"createDownloader",
|
||||||
|
"(II" JARG_STR ")" JARG_DOWNLOADER))
|
||||||
|
{
|
||||||
|
jobject jStr = methodInfo.env->NewStringUTF(hints.tempFileNameSuffix.c_str());
|
||||||
|
jobject jObj = methodInfo.env->CallStaticObjectMethod(
|
||||||
|
methodInfo.classID,
|
||||||
|
methodInfo.methodID,
|
||||||
|
_id,
|
||||||
|
hints.timeoutInSeconds,
|
||||||
|
jStr
|
||||||
|
);
|
||||||
|
_impl = methodInfo.env->NewGlobalRef(jObj);
|
||||||
|
DLLOG("android downloader: jObj: %p, _impl: %p", jObj, _impl);
|
||||||
|
sDownloaderMap.insert(make_pair(_id, this));
|
||||||
|
methodInfo.env->DeleteLocalRef(jStr);
|
||||||
|
methodInfo.env->DeleteLocalRef(jObj);
|
||||||
|
methodInfo.env->DeleteLocalRef(methodInfo.classID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloaderAndroid::~DownloaderAndroid()
|
DownloaderAndroid::~DownloaderAndroid()
|
||||||
{
|
{
|
||||||
|
if(_impl != nullptr)
|
||||||
|
{
|
||||||
|
JniMethodInfo methodInfo;
|
||||||
|
if (JniHelper::getStaticMethodInfo(methodInfo,
|
||||||
|
JCLS_DOWNLOADER,
|
||||||
|
"cancelAllRequests",
|
||||||
|
"(" JARG_DOWNLOADER ")V"))
|
||||||
|
{
|
||||||
|
methodInfo.env->CallStaticVoidMethod(
|
||||||
|
methodInfo.classID,
|
||||||
|
methodInfo.methodID,
|
||||||
|
_impl
|
||||||
|
);
|
||||||
|
methodInfo.env->DeleteLocalRef(methodInfo.classID);
|
||||||
|
}
|
||||||
|
sDownloaderMap.erase(_id);
|
||||||
|
JniHelper::getEnv()->DeleteGlobalRef(_impl);
|
||||||
|
}
|
||||||
|
DLLOG("Destruct DownloaderAndroid: %p", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDownloadTask *DownloaderAndroid::createCoTask(std::shared_ptr<const DownloadTask>& task)
|
IDownloadTask *DownloaderAndroid::createCoTask(std::shared_ptr<const DownloadTask>& task)
|
||||||
{
|
{
|
||||||
return nullptr;
|
DownloadTaskAndroid *coTask = new DownloadTaskAndroid;
|
||||||
|
coTask->task = task;
|
||||||
|
|
||||||
|
JniMethodInfo methodInfo;
|
||||||
|
if (JniHelper::getStaticMethodInfo(methodInfo,
|
||||||
|
JCLS_DOWNLOADER,
|
||||||
|
"createTask",
|
||||||
|
"(" JARG_DOWNLOADER "I" JARG_STR JARG_STR")V"))
|
||||||
|
{
|
||||||
|
jstring jstrURL = methodInfo.env->NewStringUTF(task->requestURL.c_str());
|
||||||
|
jstring jstrPath= methodInfo.env->NewStringUTF(task->storagePath.c_str());
|
||||||
|
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, _impl, coTask->id, jstrURL, jstrPath);
|
||||||
|
methodInfo.env->DeleteLocalRef(jstrURL);
|
||||||
|
methodInfo.env->DeleteLocalRef(jstrPath);
|
||||||
|
methodInfo.env->DeleteLocalRef(methodInfo.classID);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLLOG("DownloaderAndroid::createCoTask id: %d", coTask->id);
|
||||||
|
_taskMap.insert(make_pair(coTask->id, coTask));
|
||||||
|
return coTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DownloaderAndroid::_onProcess(int taskId, int64_t dl, int64_t dlNow, int64_t dlTotal)
|
||||||
|
{
|
||||||
|
DLLOG("DownloaderAndroid::onProgress(taskId: %d, dl: %lld, dlnow: %lld, dltotal: %lld)", taskId, dl, dlNow, dlTotal);
|
||||||
|
auto iter = _taskMap.find(taskId);
|
||||||
|
if (_taskMap.end() == iter)
|
||||||
|
{
|
||||||
|
DLLOG("DownloaderAndroid::onProgress can't find task with id: %d", taskId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DownloadTaskAndroid *coTask = iter->second;
|
||||||
|
function<int64_t(void*, int64_t)> transferDataToBuffer;
|
||||||
|
onTaskProgress(*coTask->task, dl, dlNow, dlTotal, transferDataToBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloaderAndroid::_onFinish(int taskId, int errCode, const char *errStr)
|
||||||
|
{
|
||||||
|
DLLOG("DownloaderAndroid::_onFinish(taskId: %d, errCode: %d, errStr: %s)", taskId, errCode, (errStr)?errStr:"null");
|
||||||
|
auto iter = _taskMap.find(taskId);
|
||||||
|
if (_taskMap.end() == iter)
|
||||||
|
{
|
||||||
|
DLLOG("DownloaderAndroid::_onFinish can't find task with id: %d", taskId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DownloadTaskAndroid *coTask = iter->second;
|
||||||
|
string str = (errStr ? errStr : "");
|
||||||
|
vector<unsigned char> data;
|
||||||
|
onTaskFinish(*coTask->task,
|
||||||
|
(errCode ? DownloadTask::ERROR_IMPL_INTERNAL : DownloadTask::ERROR_FILE_OP_FAILED),
|
||||||
|
errCode,
|
||||||
|
str,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
coTask->task.reset();
|
||||||
|
_taskMap.erase(iter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace cocos2d::network
|
} // namespace cocos2d::network
|
||||||
|
|
||||||
|
static void _nativeOnProgress(JNIEnv *env, jclass clazz, jint id, jint taskId, jlong dl, jlong dlnow, jlong dltotal)
|
||||||
|
{
|
||||||
|
DLLOG("_nativeOnProgress(id: %d, taskId: %d, dl: %lld, dlnow: %lld, dltotal: %lld)", id, taskId, dl, dlnow, dltotal);
|
||||||
|
auto iter = sDownloaderMap.find(id);
|
||||||
|
if (sDownloaderMap.end() == iter)
|
||||||
|
{
|
||||||
|
DLLOG("_nativeOnProgress can't find downloader by key: %p for task: %d", clazz, id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cocos2d::network::DownloaderAndroid *downloader = iter->second;
|
||||||
|
downloader->_onProcess((int)taskId, (int64_t)dl, (int64_t)dlnow, (int64_t)dltotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _nativeOnFinish(JNIEnv *env, jclass clazz, jint id, jint taskId, jint errCode, jstring errStr)
|
||||||
|
{
|
||||||
|
DLLOG("_nativeOnFinish(id: %d, taskId: %d)", id, taskId);
|
||||||
|
auto iter = sDownloaderMap.find(id);
|
||||||
|
if (sDownloaderMap.end() == iter)
|
||||||
|
{
|
||||||
|
DLLOG("_nativeOnFinish can't find downloader id: %d for task: %d", id, taskId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cocos2d::network::DownloaderAndroid *downloader = iter->second;
|
||||||
|
if (errStr)
|
||||||
|
{
|
||||||
|
const char *nativeErrStr = nullptr;
|
||||||
|
env->GetStringUTFChars(errStr, JNI_FALSE);
|
||||||
|
downloader->_onFinish((int)taskId, (int)errCode, nativeErrStr);
|
||||||
|
env->ReleaseStringUTFChars(errStr, nativeErrStr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
downloader->_onFinish((int)taskId, (int)errCode, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static JNINativeMethod sMethodTable[] = {
|
||||||
|
{ "nativeOnProgress", "(IIJJJ)V", (void*)_nativeOnProgress },
|
||||||
|
{ "nativeOnFinish", "(III" JARG_STR ")V", (void*)_nativeOnFinish },
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool _registerNativeMethods(JNIEnv* env)
|
||||||
|
{
|
||||||
|
jclass clazz = env->FindClass(JCLS_DOWNLOADER);
|
||||||
|
if (clazz == NULL)
|
||||||
|
{
|
||||||
|
DLLOG("_registerNativeMethods: can't find java class:%s", JARG_DOWNLOADER);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (JNI_OK != env->RegisterNatives(clazz, sMethodTable, sizeof(sMethodTable) / sizeof(sMethodTable[0])))
|
||||||
|
{
|
||||||
|
DLLOG("_registerNativeMethods: failed");
|
||||||
|
if (env->ExceptionCheck())
|
||||||
|
{
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include "network/CCIDownloaderImpl.h"
|
#include "network/CCIDownloaderImpl.h"
|
||||||
|
|
||||||
|
class _jobject;
|
||||||
|
|
||||||
namespace cocos2d { namespace network
|
namespace cocos2d { namespace network
|
||||||
{
|
{
|
||||||
class DownloadTaskAndroid;
|
class DownloadTaskAndroid;
|
||||||
|
@ -39,9 +41,13 @@ namespace cocos2d { namespace network
|
||||||
|
|
||||||
virtual IDownloadTask *createCoTask(std::shared_ptr<const DownloadTask>& task) override;
|
virtual IDownloadTask *createCoTask(std::shared_ptr<const DownloadTask>& task) override;
|
||||||
|
|
||||||
|
// designed called by internal
|
||||||
|
void _onProcess(int taskId, int64_t dl, int64_t dlNow, int64_t dlTotal);
|
||||||
|
void _onFinish(int taskId, int errCode, const char *errStr);
|
||||||
protected:
|
protected:
|
||||||
class Impl;
|
int _id;
|
||||||
std::shared_ptr<Impl> _impl;
|
_jobject* _impl;
|
||||||
|
std::unordered_map<int, DownloadTaskAndroid*> _taskMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace cocos2d::network
|
}} // namespace cocos2d::network
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#define DownloaderImpl DownloaderApple
|
#define DownloaderImpl DownloaderApple
|
||||||
|
|
||||||
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
#include <unordered_map> // temp
|
|
||||||
#include "network/CCDownloader-android.h"
|
#include "network/CCDownloader-android.h"
|
||||||
#define DownloaderImpl DownloaderAndroid
|
#define DownloaderImpl DownloaderAndroid
|
||||||
|
|
||||||
|
@ -107,14 +107,15 @@ namespace cocos2d { namespace network {
|
||||||
std::vector<unsigned char>& data)
|
std::vector<unsigned char>& data)
|
||||||
{
|
{
|
||||||
if (DownloadTask::ERROR_NO_ERROR != errorCode)
|
if (DownloadTask::ERROR_NO_ERROR != errorCode)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (onTaskError)
|
if (onTaskError)
|
||||||
{
|
{
|
||||||
onTaskError(task, errorCode, errorCodeInternal, errorStr);
|
onTaskError(task, errorCode, errorCodeInternal, errorStr);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// success callback
|
||||||
if (task.storagePath.length())
|
if (task.storagePath.length())
|
||||||
{
|
{
|
||||||
if (onFileTaskSuccess)
|
if (onFileTaskSuccess)
|
||||||
|
|
|
@ -25,7 +25,7 @@ THE SOFTWARE.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "base/CCConsole.h"
|
#include "base/CCConsole.h"
|
||||||
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
package org.cocos2dx.lib;
|
||||||
|
|
||||||
|
import com.loopj.android.http.AsyncHttpClient;
|
||||||
|
import com.loopj.android.http.FileAsyncHttpResponseHandler;
|
||||||
|
import com.loopj.android.http.RequestHandle;
|
||||||
|
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.message.BasicHeader;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class FileTaskHandler extends FileAsyncHttpResponseHandler {
|
||||||
|
int _id;
|
||||||
|
File _finalFile;
|
||||||
|
|
||||||
|
private long _initFileLen;
|
||||||
|
private long _lastBytesWritten;
|
||||||
|
private Cocos2dxDownloader _downloader;
|
||||||
|
|
||||||
|
void LogD(String msg) {
|
||||||
|
android.util.Log.d("Cocos2dxDownloader", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileTaskHandler(Cocos2dxDownloader downloader, int id, File temp, File finalFile) {
|
||||||
|
super(temp, true);
|
||||||
|
_finalFile = finalFile;
|
||||||
|
_downloader = downloader;
|
||||||
|
_id = id;
|
||||||
|
_initFileLen = getTargetFile().length();
|
||||||
|
_lastBytesWritten = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgress(long bytesWritten, long totalSize) {
|
||||||
|
//LogD("onProgress(bytesWritten:" + bytesWritten + " totalSize:" + totalSize);
|
||||||
|
long dlBytes = bytesWritten - _lastBytesWritten;
|
||||||
|
long dlNow = bytesWritten + _initFileLen;
|
||||||
|
long dlTotal = totalSize + _initFileLen;
|
||||||
|
_downloader.onProgress(_id, dlBytes, dlNow, dlTotal);
|
||||||
|
_lastBytesWritten = bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
_downloader.onStart(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
// onFinish called after onSuccess/onFailure
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(int i, Header[] headers, Throwable throwable, File file) {
|
||||||
|
LogD("onFailure(i:" + i + " headers:" + headers.toString() + " throwable:" + throwable + " file:" + file);
|
||||||
|
_downloader.onFinish(_id, i, throwable.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(int i, Header[] headers, File file) {
|
||||||
|
LogD("onSuccess(i:" + i + " headers:" + headers.toString() + " file:" + file);
|
||||||
|
String errStr = null;
|
||||||
|
do {
|
||||||
|
// rename temp file to final file
|
||||||
|
// if final file exist, remove it
|
||||||
|
if (_finalFile.exists()) {
|
||||||
|
if (_finalFile.isDirectory()) {
|
||||||
|
errStr = "Dest file is directory:" + _finalFile.getAbsolutePath();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (false == _finalFile.delete()) {
|
||||||
|
errStr = "Can't remove old file:" + _finalFile.getAbsolutePath();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File tempFile = getTargetFile();
|
||||||
|
tempFile.renameTo(_finalFile);
|
||||||
|
} while (false);
|
||||||
|
_downloader.onFinish(_id, 0, errStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadTask {
|
||||||
|
|
||||||
|
DownloadTask() {
|
||||||
|
handle = null;
|
||||||
|
fileHandler = null;
|
||||||
|
resetStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetStatus() {
|
||||||
|
finished = false;
|
||||||
|
bytesReceived = 0;
|
||||||
|
totalBytesReceived = 0;
|
||||||
|
totalBytesExpected = 0;
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestHandle handle;
|
||||||
|
FileTaskHandler fileHandler;
|
||||||
|
|
||||||
|
boolean finished;
|
||||||
|
|
||||||
|
// progress
|
||||||
|
long bytesReceived;
|
||||||
|
long totalBytesReceived;
|
||||||
|
long totalBytesExpected;
|
||||||
|
byte[] data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Cocos2dxDownloader {
|
||||||
|
private int _id;
|
||||||
|
private AsyncHttpClient _httpClient = new AsyncHttpClient();
|
||||||
|
private String _tempFileNameSufix;
|
||||||
|
private HashMap _taskMap = new HashMap();
|
||||||
|
|
||||||
|
void onProgress(final int id, final long downloadBytes, final long downloadNow, final long downloadTotal) {
|
||||||
|
DownloadTask task = (DownloadTask)_taskMap.get(id);
|
||||||
|
if (null != task) {
|
||||||
|
task.bytesReceived = downloadBytes;
|
||||||
|
task.totalBytesReceived = downloadNow;
|
||||||
|
task.totalBytesExpected = downloadTotal;
|
||||||
|
}
|
||||||
|
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeOnProgress(_id, id, downloadBytes, downloadNow, downloadTotal);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStart(int id) {
|
||||||
|
DownloadTask task = (DownloadTask)_taskMap.get(id);
|
||||||
|
if (null != task) {
|
||||||
|
task.resetStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFinish(final int id, final int errCode, final String errStr) {
|
||||||
|
DownloadTask task = (DownloadTask)_taskMap.get(id);
|
||||||
|
if (null == task) return;
|
||||||
|
_taskMap.remove(id);
|
||||||
|
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeOnFinish(_id, id, errCode, errStr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cocos2dxDownloader createDownloader(int id, int timeoutInSeconds, String tempFileNameSufix) {
|
||||||
|
Cocos2dxDownloader downloader = new Cocos2dxDownloader();
|
||||||
|
downloader._id = id;
|
||||||
|
|
||||||
|
downloader._httpClient.setEnableRedirects(true);
|
||||||
|
if (timeoutInSeconds > 0) {
|
||||||
|
downloader._httpClient.setTimeout(timeoutInSeconds * 1000);
|
||||||
|
}
|
||||||
|
// downloader._httpClient.setMaxRetriesAndTimeout(3, timeoutInSeconds * 1000);
|
||||||
|
downloader._httpClient.allowRetryExceptionClass(javax.net.ssl.SSLException.class);
|
||||||
|
|
||||||
|
downloader._tempFileNameSufix = tempFileNameSufix;
|
||||||
|
return downloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createTask(final Cocos2dxDownloader downloader, int id_, String url_, String path_) {
|
||||||
|
final int id = id_;
|
||||||
|
final String url = url_;
|
||||||
|
final String path = path_;
|
||||||
|
|
||||||
|
Cocos2dxHelper.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DownloadTask task = new DownloadTask();
|
||||||
|
do {
|
||||||
|
File tempFile = new File(path + downloader._tempFileNameSufix);
|
||||||
|
if (tempFile.isDirectory()) break;
|
||||||
|
|
||||||
|
File parent = tempFile.getParentFile();
|
||||||
|
if (!parent.isDirectory() && !parent.mkdirs()) break;
|
||||||
|
|
||||||
|
File finalFile = new File(path);
|
||||||
|
if (tempFile.isDirectory()) break;
|
||||||
|
|
||||||
|
task.fileHandler = new FileTaskHandler(downloader, id, tempFile, finalFile);
|
||||||
|
Header[] headers = null;
|
||||||
|
long fileLen = tempFile.length();
|
||||||
|
if (fileLen > 0) {
|
||||||
|
// continue download
|
||||||
|
List<Header> list = new ArrayList<Header>();
|
||||||
|
list.add(new BasicHeader("Range", "bytes=" + fileLen + "-"));
|
||||||
|
headers = list.toArray(new Header[list.size()]);
|
||||||
|
}
|
||||||
|
task.handle = downloader._httpClient.get(Cocos2dxHelper.getActivity(), url, headers, null, task.fileHandler);
|
||||||
|
//task.handle = downloader._httpClient.get(url, task.fileHandler);
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (null == task.handle) {
|
||||||
|
final String errStr = "Can't create DownloadTask for " + url;
|
||||||
|
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
downloader.nativeOnFinish(downloader._id, id, 0, errStr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
downloader._taskMap.put(id, task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelAllRequests(final Cocos2dxDownloader downloader) {
|
||||||
|
Cocos2dxHelper.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
//downloader._httpClient.cancelAllRequests(true);
|
||||||
|
Iterator iter = downloader._taskMap.entrySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Map.Entry entry = (Map.Entry) iter.next();
|
||||||
|
//Object key = entry.getKey();
|
||||||
|
DownloadTask task = (DownloadTask)entry.getValue();
|
||||||
|
if (null != task.handle) {
|
||||||
|
task.handle.cancel(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
native void nativeOnProgress(int id, int taskId, long dl, long dlnow, long dltotal);
|
||||||
|
native void nativeOnFinish(int id, int taskId, int errCode, String errStr);
|
||||||
|
}
|
|
@ -26,5 +26,5 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: '../java/libs', include: ['*.jar'])
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ void DownloaderBaseTest::progressCallback(const network::DownloadTask& task,
|
||||||
|
|
||||||
void DownloaderBaseTest::successCallback(const network::DownloadTask& task)
|
void DownloaderBaseTest::successCallback(const network::DownloadTask& task)
|
||||||
{
|
{
|
||||||
cocos2d::log("download finished: %s", task.storagePath.c_str());
|
cocos2d::log("download successed: %s", task.storagePath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue