[android] Used bind for ZipReader::UnzipFile callback impl

This commit is contained in:
Alex Zolotarev 2012-02-27 01:58:32 +03:00 committed by Alex Zolotarev
parent fb02b19b4c
commit d10d0e4ada
4 changed files with 41 additions and 53 deletions

View file

@ -12,9 +12,7 @@
#include "../../../../../std/vector.hpp"
#include "../../../../../std/string.hpp"
#include "../jni/jni_thread.hpp"
#include "../jni/jni_method.hpp"
#include "../../../../../std/bind.hpp"
// Special error codes to notify GUI about free space
//@{
@ -38,12 +36,6 @@ static jint g_copiedBytesProgress = 0;
extern "C"
{
JNIEXPORT jint JNICALL
Java_com_mapswithme_maps_CopyResourcesActivity_nativeGetCopiedBytes(JNIEnv * env, jobject thiz)
{
return g_copiedBytesProgress;
}
JNIEXPORT jint JNICALL
Java_com_mapswithme_maps_CopyResourcesActivity_nativeGetBytesToCopy(JNIEnv * env, jobject thiz,
jstring apkPath, jstring sdcardPath)
@ -99,21 +91,14 @@ extern "C"
return totalSizeToCopy;
}
jobject g_observer = 0;
jni::Method * g_progressFn = 0;
int g_cycles = 0;
void CopyFileProgress(int size, int pos)
void CopyFileProgress(JNIEnv * env, jobject obj, jmethodID method, int size, int pos)
{
g_cycles++;
/// calling JNI method only once in 5 cycles, as there
/// are an overhead on frequent calls.
if ((g_cycles %=5) == 0)
g_progressFn->CallVoid(g_observer, size, pos);
env->CallVoidMethod(obj, method, size, pos);
}
JNIEXPORT jint JNICALL
Java_com_mapswithme_maps_CopyResourcesActivity_nativeCopyNextFile(JNIEnv * env, jobject thiz, jobject observer)
Java_com_mapswithme_maps_CopyResourcesActivity_nativeCopyNextFile(JNIEnv * env,
jobject thiz, jobject observer)
{
if (g_filesToCopy.empty())
return ERR_COPIED_SUCCESSFULLY;
@ -132,27 +117,21 @@ extern "C"
return ERR_NOT_ENOUGH_FREE_SPACE;
}
jclass k = jni::GetCurrentThreadJNIEnv()->GetObjectClass(observer);
g_progressFn = new jni::Method(k, "onFileProgress", "(II)V");
g_observer = observer;
g_cycles = 0;
jmethodID method = env->GetMethodID(env->GetObjectClass(observer), "onFileProgress", "(II)V");
CHECK(method, ("Not existing method: void onFileProgress(int,int)"));
// Perform copying
try
{
ZipFileReader::UnzipFile(g_apkPath, it->m_pathInZip, it->m_pathInSdcard, &CopyFileProgress);
ZipFileReader::UnzipFile(g_apkPath, it->m_pathInZip, it->m_pathInSdcard,
bind(CopyFileProgress, env, observer, method, _1, _2));
}
catch (std::exception const & e)
{
LOG(LERROR, ("Error while extracting", it->m_pathInZip, "from apk to", it->m_pathInSdcard));
delete g_progressFn;
g_observer = 0;
return ERR_NOT_ENOUGH_FREE_SPACE;
}
g_observer = 0;
delete g_progressFn;
g_copiedBytesProgress += it->m_uncompressedSize;
g_filesToCopy.erase(it);
return g_copiedBytesProgress;

View file

@ -10,7 +10,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
// MWM resources are zipped in the apk inside /assets folder.
// MWM code currently can't randomly read zip files, so they're copied
@ -30,7 +29,7 @@ public class CopyResourcesActivity extends Activity
{
private final String m_apkPath;
private final String m_sdcardPath;
CopyResourcesTask(String apkPath, String sdcardPath)
{
m_apkPath = apkPath;
@ -79,26 +78,28 @@ public class CopyResourcesActivity extends Activity
CopyResourcesActivity.this.onCopyResourcesProgress(copiedBytes[0]);
}
// If negative, stores error code
// Total number of copied bytes
int m_bytesCopied = 0;
protected void onFileProgress(int size, int pos)
{
publishProgress(nativeGetCopiedBytes() + pos);
publishProgress(m_bytesCopied + pos);
}
@Override
protected Integer doInBackground(Void... p)
{
// If negative, stores error code
int bytesCopied;
do
{
bytesCopied = nativeCopyNextFile(this);
if (bytesCopied > 0)
publishProgress(new Integer(bytesCopied));
else if (bytesCopied < 0)
return new Integer(bytesCopied);
} while (bytesCopied != 0);
m_bytesCopied = nativeCopyNextFile(this);
if (m_bytesCopied > 0)
publishProgress(m_bytesCopied);
else if (m_bytesCopied < 0)
return m_bytesCopied;
} while (m_bytesCopied != 0);
return new Integer(ERR_COPIED_SUCCESSFULLY);
return ERR_COPIED_SUCCESSFULLY;
}
}
@ -152,22 +153,25 @@ public class CopyResourcesActivity extends Activity
}
}
private String getProgressString(int current, int total)
private String cutProgressString(final String str, int current, int total)
{
final String str = getString(R.string.app_name);
int len = current * str.length() / total;
if (len <= 0)
len = 0;
else if (len > str.length())
len = str.length();
return String.format(getString(R.string.loading), str.substring(0, len));
return str.substring(0, len);
}
private String m_progressString;
@Override
protected Dialog onCreateDialog(int totalBytesToCopy)
{
m_progressString = getString(R.string.loading);
m_dialog = new ProgressDialog(this);
m_dialog.setMessage(getProgressString(0, totalBytesToCopy));
m_dialog.setMessage(cutProgressString(m_progressString, 0, totalBytesToCopy));
m_dialog.setCancelable(false);
m_dialog.setIndeterminate(true);
m_dialog.setMax(totalBytesToCopy);
@ -178,13 +182,12 @@ public class CopyResourcesActivity extends Activity
{
if (m_dialog != null)
{
m_dialog.setMessage(getProgressString(copiedBytes, m_dialog.getMax()));
m_dialog.setMessage(cutProgressString(m_progressString, copiedBytes, m_dialog.getMax()));
m_dialog.setProgress(copiedBytes);
}
}
private native void nativeMoveMaps(String fromFolder, String toFolder);
private native int nativeGetBytesToCopy(String m_apkPath, String m_sdcardPath);
private native int nativeGetCopiedBytes();
private native int nativeCopyNextFile(Object observer);
}

View file

@ -92,14 +92,15 @@ void ZipFileReader::UnzipFile(string const & zipContainer, string const & fileIn
MY_SCOPE_GUARD(currentFileGuard, bind(&unzCloseCurrentFile, zip));
static size_t const BUF_SIZE = 1024 * 50;
char * buf = new char[BUF_SIZE];
try
{
FileWriter outFile(outFilePath);
int pos = 0;
int readBytes;
static size_t const BUF_SIZE = 4096;
char buf[BUF_SIZE];
while (true)
{
readBytes = unzReadCurrentFile(zip, buf, BUF_SIZE);
@ -118,9 +119,12 @@ void ZipFileReader::UnzipFile(string const & zipContainer, string const & fileIn
}
catch (Exception const & e)
{
delete[] buf;
// Delete unfinished output file
FileWriter::DeleteFileX(outFilePath);
// Rethrow exception - we've failed
throw;
}
delete[] buf;
}

View file

@ -11,6 +11,8 @@
#include "../base/exception.hpp"
#include "../std/function.hpp"
class ZipFileReader : public BaseZipFileReaderType
{
private:
@ -18,7 +20,7 @@ private:
public:
typedef void (*ProgressFn)(int, int);
typedef function<void(int, int)> ProgressFn;
DECLARE_EXCEPTION(OpenZipException, OpenException);
DECLARE_EXCEPTION(LocateZipException, OpenException);
@ -31,7 +33,7 @@ public:
/// @warning Can also throw Writer::OpenException and Writer::WriteException
static void UnzipFile(string const & zipContainer, string const & fileInZip,
string const & outFilePath, ProgressFn progressFn = 0);
string const & outFilePath, ProgressFn progressFn = ProgressFn());
static vector<string> FilesList(string const & zipContainer);
/// Quick version without exceptions