Android 应用程序中的预加载数据库损坏问题
我有一个 Android 应用程序,首先在异步任务中将大型数据库下载到 SD 卡(略多于 50MB)。下载代码如下。
HttpURLConnection conexion = (HttpURLConnection) url.openConnection();
if(filePath.exists() && filePath.length() > 10000.00)
{
downloaded = (int) filePath.length();
conexion.setRequestProperty("Range", "bytes=" + (filePath.length()) + "-");
}
else
conexion.setRequestProperty("Range", "bytes=" + downloaded + "-");
conexion.setDoInput(true);
conexion.setDoOutput(true);
conexion.setUseCaches(false);
conexion.connect();
...
try {
totalFileLength = lengthOfFile + downloaded;
progressDialog.setMax(lengthOfFile + downloaded);
// downlod the file
input = new BufferedInputStream(conexion.getInputStream());
output = (downloaded==0)? new FileOutputStream(filePath): new FileOutputStream(filePath,true);
bout = new BufferedOutputStream(output, 1024);
byte data[] = new byte[1024];
while ((count = input.read(data, 0, 1024)) >= 0 && running) {
downloaded += count;
// publishing the progress....
//onProgressUpdate((int)(downloaded*100/lengthOfFile));
progressDialog.setProgress(downloaded);
bout.write(data, 0, count);
}
} catch (Exception e) {
...
} finally {
try {
input.close();
bout.flush();
bout.close();
} catch(IOException e) {
...
}
}
完全下载文件后,我打开数据库并向其中添加一个表。
try {
myDbHelper.myDataBase.execSQL("CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)");
success = true;
} catch (SQLException sqle) {
throw sqle;
}
现在,这段代码在我运行它的每台设备上都运行得很好,但我的一些用户在 execSQL 行上遇到了这个错误。似乎它不能单独在 Samsung Galaxy SII 上运行(没有任何其他手机出现此错误的投诉和后续堆栈跟踪),但我不完全确定它只是这款手机。
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.daleroy.fungifieldguide/net.daleroy.fungifieldguide.activities.FungiFieldGuide}: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)
at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1904)
at net.daleroy.fungifieldguide.services.MushroomService.MakeFavoriteTable(MushroomService.java:118)
at net.daleroy.fungifieldguide.services.MushroomService.OpenDB(MushroomService.java:64)
at net.daleroy.fungifieldguide.activities.FungiFieldGuide.onCreate(FungiFieldGuide.java:73)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
我收到了使用 sgs2 的用户下载的数据库副本,并且该文件的校验和已关闭。当我使用 sqlite 管理器(firefox 插件)打开文件时,我也看不到文件中的任何数据或数据结构。我让他直接下载数据库的副本并将其放在他的数据文件夹中,应用程序运行良好。所以问题出在下载过程中的某个地方。
I have an android application that begins by downloading a large database to the sdcard (a little over 50mb) in an asynctask. The download code is as follows.
HttpURLConnection conexion = (HttpURLConnection) url.openConnection();
if(filePath.exists() && filePath.length() > 10000.00)
{
downloaded = (int) filePath.length();
conexion.setRequestProperty("Range", "bytes=" + (filePath.length()) + "-");
}
else
conexion.setRequestProperty("Range", "bytes=" + downloaded + "-");
conexion.setDoInput(true);
conexion.setDoOutput(true);
conexion.setUseCaches(false);
conexion.connect();
...
try {
totalFileLength = lengthOfFile + downloaded;
progressDialog.setMax(lengthOfFile + downloaded);
// downlod the file
input = new BufferedInputStream(conexion.getInputStream());
output = (downloaded==0)? new FileOutputStream(filePath): new FileOutputStream(filePath,true);
bout = new BufferedOutputStream(output, 1024);
byte data[] = new byte[1024];
while ((count = input.read(data, 0, 1024)) >= 0 && running) {
downloaded += count;
// publishing the progress....
//onProgressUpdate((int)(downloaded*100/lengthOfFile));
progressDialog.setProgress(downloaded);
bout.write(data, 0, count);
}
} catch (Exception e) {
...
} finally {
try {
input.close();
bout.flush();
bout.close();
} catch(IOException e) {
...
}
}
After downloading the file completely I open the database and add a table to it.
try {
myDbHelper.myDataBase.execSQL("CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)");
success = true;
} catch (SQLException sqle) {
throw sqle;
}
Now, this code works wonderfully on every device I run it on, but several of my users are getting this error on the execSQL line. It seems like it is not working on the Samsung Galaxy SII alone (there hasn't been a complaint and subsequent stacktrace with this error with any other phone) but I'm not entirely sure its just this phone.
java.lang.RuntimeException: Unable to start activity ComponentInfo{net.daleroy.fungifieldguide/net.daleroy.fungifieldguide.activities.FungiFieldGuide}: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: CREATE TABLE IF NOT EXISTS FAVORITES (_id integer primary key autoincrement, MushroomID INTEGER)
at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1904)
at net.daleroy.fungifieldguide.services.MushroomService.MakeFavoriteTable(MushroomService.java:118)
at net.daleroy.fungifieldguide.services.MushroomService.OpenDB(MushroomService.java:64)
at net.daleroy.fungifieldguide.activities.FungiFieldGuide.onCreate(FungiFieldGuide.java:73)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
I've received a copy of the database downloaded from a user with a sgs2 and the checksum of the file is off. I also cannot see any data or data structure in the file when I open with sqlite manager (firefox plugin). I let him download a copy of the database directly and place it in his data folder and the application works fine. So the problem is somewhere in the download process.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从 API 级别 9 (Android 2.3) 开始,您可以使用
DownloadManager
来处理长时间运行的 HTTP 下载:
以下是演示 DownloadManager 用法的示例项目:Android DownloadManager 示例< /a>.
我认为您甚至可以尝试将 DownloadManager 向后移植到以前的 Android 版本(如果您需要支持它们)。其源代码可以在这里找到:DownloadManager.java
Starting from the API level 9 (Android 2.3) you can use
DownloadManager
to handle long-running HTTP downloads:Here is the example project which demonstrates DownloadManager usage: Android DownloadManager Example.
I think you can even try to backport DownloadManager to the previous Android versions (if you need to support them). Its source code can be found here: DownloadManager.java
你在你的输出流上调用flush和close吗?就像这样:
如果没有,我会从那开始。我下载了一个具有类似代码的视频,发现对于某些设备和某些不调用刷新的视频会损坏并使其无法播放
are you calling flush and close on your outputstream? Like this:
If not I would start with that. I downloaded a video with similar code and found that for some devices and some videos not calling flush was corrupting and making it unplayable
这是另一个讨论这种数据库损坏的问题 Android - 数据库磁盘映像格式错误< /a>.
如果在这种状态下您无法修复数据库,也许您可以在出现此错误时尝试再次下载(假设此问题很少见,并且再次下载数据库可以解决问题)。
Here is another question that talks about this kind of database corruption Android - database disk image is malformed.
If you can't fix the database when its in this state, maybe you can try to download it again if and when this error occurs (assuming that this problem is rare and downloading the database again can fix the problem).