Java 从大型数据库读取数据

Java 从大型数据库读取数据,java,android,database,sqlite,android-sqlite,Java,Android,Database,Sqlite,Android Sqlite,我正在编写一个应用程序,需要从数据库中加载和读取。这个数据库大约有900MB。当我将其复制到应用程序目录中的\assets\databases时,android studio上会弹出一个java堆空间错误。我使用org.gradle.jvmargs=-Xmx4608m增加了堆空间。我还尝试了在网上找到的其他解决方案,但我的问题仍然存在。我也知道apk文件应该有多大是有限制的。这可能导致java堆空间错误,因为我的数据库太大,无法作为apk的一部分加载 有什么替代方案?如何从android应用程序

我正在编写一个应用程序,需要从数据库中加载和读取。这个数据库大约有900MB。当我将其复制到应用程序目录中的\assets\databases时,android studio上会弹出一个java堆空间错误。我使用org.gradle.jvmargs=-Xmx4608m增加了堆空间。我还尝试了在网上找到的其他解决方案,但我的问题仍然存在。我也知道apk文件应该有多大是有限制的。这可能导致java堆空间错误,因为我的数据库太大,无法作为apk的一部分加载

有什么替代方案?如何从android应用程序读取数据库,而不将数据库物理保存在.apk文件中

以下是生成错误的堆栈跟踪

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:packageDebug'.
> Java heap space

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:packageDebug'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:63)
    at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
    at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:124)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:80)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:105)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:99)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:625)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:580)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:99)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: org.gradle.tooling.BuildException: Java heap space
    at com.android.build.gradle.internal.scope.OutputScope.lambda$parallelForEachOutput$10(OutputScope.java:241)
    at com.android.build.gradle.internal.scope.OutputScope.parallelForEachOutput(OutputScope.java:236)
    at com.android.build.gradle.internal.scope.OutputScope.parallelForEachOutput(OutputScope.java:197)
    at com.android.build.gradle.internal.scope.OutputScope.parallelForEachOutput(OutputScope.java:181)
    at com.android.build.gradle.tasks.PackageAndroidArtifact.doFullTaskAction(PackageAndroidArtifact.java:471)
    at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:109)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
    at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$IncrementalTaskAction.doExecute(DefaultTaskClassInfoStore.java:173)
    at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134)
    at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:121)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:122)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:111)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
    ... 27 more
Caused by: java.lang.OutOfMemoryError: Java heap space
    at com.google.common.io.ByteStreams.toByteArray(ByteStreams.java:165)
    at com.android.apkzlib.zip.StoredEntry.read(StoredEntry.java:346)
    at com.android.apkzlib.sign.SigningExtension.onZipEntryOutput(SigningExtension.java:256)
    at com.android.apkzlib.sign.SigningExtension.access$400(SigningExtension.java:55)
    at com.android.apkzlib.sign.SigningExtension$1.lambda$added$0(SigningExtension.java:164)
    at com.android.apkzlib.sign.SigningExtension$1$$Lambda$378/1751952517.run(Unknown Source)
    at com.android.apkzlib.zip.ZFile.notify(ZFile.java:2099)
    at com.android.apkzlib.zip.ZFile.addToEntries(ZFile.java:1746)
    at com.android.apkzlib.zip.ZFile.processAllReadyEntries(ZFile.java:1687)
    at com.android.apkzlib.zip.ZFile.processAllReadyEntriesWithWait(ZFile.java:1708)
    at com.android.apkzlib.zip.ZFile.hasPendingChangesWithWait(ZFile.java:2517)
    at com.android.apkzlib.zfile.ApkZFileCreator.hasPendingChangesWithWait(ApkZFileCreator.java:180)
    at com.android.builder.internal.packaging.IncrementalPackager.hasPendingChangesWithWait(IncrementalPackager.java:319)
    at com.android.build.gradle.tasks.PackageAndroidArtifact.doTask(PackageAndroidArtifact.java:694)
    at com.android.build.gradle.tasks.PackageAndroidArtifact.splitFullAction(PackageAndroidArtifact.java:522)
    at com.android.build.gradle.tasks.PackageAndroidArtifact$$Lambda$327/1788085017.processSplit(Unknown Source)
    at com.android.build.gradle.internal.scope.OutputScope.lambda$parallelForEachOutput$6(OutputScope.java:186)
    at com.android.build.gradle.internal.scope.OutputScope$$Lambda$328/436614112.processSplit(Unknown Source)
    at com.android.build.gradle.internal.scope.OutputScope.lambda$parallelForEachOutput$7(OutputScope.java:203)
    at com.android.build.gradle.internal.scope.OutputScope$$Lambda$329/792075765.processSplit(Unknown Source)
    at com.android.build.gradle.internal.scope.OutputScope.lambda$null$8(OutputScope.java:225)
    at com.android.build.gradle.internal.scope.OutputScope$$Lambda$331/1881111235.call(Unknown Source)
    at com.android.ide.common.internal.WaitableExecutor.waitForAllTasks(WaitableExecutor.java:215)
    at com.android.build.gradle.internal.scope.OutputScope.parallelForEachOutput(OutputScope.java:235)
    at com.android.build.gradle.internal.scope.OutputScope.parallelForEachOutput(OutputScope.java:197)
        at     com.android.build.gradle.internal.scope.OutputScope.parallelForEachOutput(Output    Scope.java:181)


    * Get more help at https://help.gradle.org

     BUILD FAILED in 3m 24s

使用RESTAPI?说真的,在每个设备上都有这么大的数据库是非常罕见的,想象一下你们想要更新应用程序——用户每次都应该重新下载整个应用程序


若你们需要在设备上有那个么大的数据库,你们应该有SQL脚本,你们可以下载并在应用程序启动时执行。这可以解决更新的问题。但无论如何,您都应该有一些web服务。

正如我基本上同意前面的答案,我可以根据用户体验建议一种混合方法:

您需要在微调器、过滤器和其他使用的小部件上显示的任何数据都需要超快响应,最好有一个应用程序内数据库。 任何由搜索/筛选功能显示的数据或具有大量数据的数据都应该由外部实体外部bd连接、web_服务等提供。您必须知道以任何形式实现web数据库服务器的方法。我的建议是MySql,但这至少需要一个主机。
拥有一个大的数据库会有很多可以绕过的实现墙,但需要付出很多努力

使用sqlite查询可以将stacktrace复制粘贴到这里吗?@ValentinMichalak刚刚添加了stacktrace。@pskink stacktrace已添加。希望这有帮助:那么,在android apk上加载大型数据库实际上是不可能的,还是不可行?如果是后者,那么如何解决java堆空间错误?@user7331538指出,您可以用一种非常巧妙的方式来解决,但正如您所提到的,这是不实际的。gradle.properties中的org.gradle.jvmargs=-Xmx4096m允许我用800mb的文件构建一个应用程序,所以如果你确定你在做什么,这是唯一的方法