作业素材运行报错

作业素材运行报错

运行下载的作业素材 menudemo ,会提示错误 android.database.sqlite.SQLiteException: no such table: dish_tb 

http://img1.sycdn.imooc.com//climg/5cfe6eb400014eef26400364.jpg

但是生成出来的数据库文件是有 dish_tb 的

http://img1.sycdn.imooc.com//climg/5cfe6e800001d87204600270.jpg

http://img1.sycdn.imooc.com//climg/5cfe6e84000117a314000818.jpg


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

5回答
喝白酒的兔子 2019-11-13 17:31:26

通过几个小时的折腾终于找出了真正原因:

SQLiteLog: (1) no such table: dish_tb   运行项目提示找不到表的原因分析

 

这个项目运行逻辑如下:

1、项目的原始数据库在menudemo\src\main\assets目录下。

2、当执行MainActivity类的onCreate方法时会调用 generateDatabase() 方法把assets目录下的menu.db数据库拷贝到APP的文件目录下,拷贝过去的文件名为 imooc_menu.db。

3、当数据库拷贝到APP文件目录下后,开始调用MenuDao类的静态方法getInstance()获取数据库实例,注意这是一个单例模式,同时MenuProvider内容提供器类也是通过getInstance()方法获取数据库实例来对外提供数据的。

4、在MainActivity类的onCreate方法中获取到数据库实例后就查询dish_tb表中的数据进行打印并显示到TextView中。

 

正常来说,这个逻辑并没有什么问题,因为待拷贝的menu.db数据库中确实存在dish_tb表,但是查询的时候却出现了找不到dish_tb表的问题,经过反复折腾最终找出来问题所在。

 

找不到到dish_tb表的原因就是MenuProvider内容提供器要先于MainActivity类初始化,这么一来,拷贝数据库的方法是在MainActivity类中的,这个时候拷贝数据库的方法generateDatabase() 是还没有执行的,所以这个时候APP的文件目录下是没有imooc_menu.db数据库的,而这个时候MenuProvider内容提供器类的onCreate方法会调用MenuDao.getInstance()这个方法去获取数据库实例,当创建数据库对象的时候如果没有imooc_menu.db这个文件存在的话,就直接创建了一个新数据库,然后就把这个新数据库对象返回给了内容提供器。当内容提供器初始化完成了后轮到MainActivity类进行初始化,MainActivity类拷贝menu.db数据库到APP目录下命名为imooc_menu.db(这个时候是覆盖了之前创建的新数据库),接着调用MenuDao.getInstance()获取数据库对象,因为是单例模式,获取到的对象还是原先的新数据库对象(这是重点),接着进行查询操作,这样当然是无法在新数据库中找到dish_tb表的了,所以APP崩溃了。

 

解决方法1:删除掉文件路面下的imooc_menu.db-shm 和 imooc_menu.db-wal文件,因为不删除这两个文件的话再次启动还是获取到那个没有包含dish_tb表的数据库实例,关于这两个文件的作用百度即可明白。删除这两个文件后再次运行,这次不会崩溃了,因为这次获取到的数据库实例是上一次崩溃的时候复制过去的数据库实例,而这个数据库是包含了dish_tb表的。

解决方法2:让拷贝数据库的方法在内容提供器调用MenuDao.getInstance()方法获取实例之前执行就解决了崩溃的问题。

下图是要删除的两个文件:

http://img1.sycdn.imooc.com//climg/5dcbcc0609d6931e00000000.jpg


关于内容提供器和MainActivity谁先初始化,看下图就明白了:

http://img1.sycdn.imooc.com//climg/5dcbcc3c09eba6f510720879.jpg

喝白酒的兔子 2019-11-13 14:14:18

我也是这个问题,你现在解决了没有?

  • 先把查询语句注释掉,等创建后可以再打开
    2019-11-13 15:51:47
  • 我的并没有用,我现在找出问题了,把MenuProvider类的onCreate方法中的db = MenuDao.getInstance(getContext()); 注释掉就好了。
    2019-11-13 16:00:03
森林之王2 2019-08-25 13:36:55

先注释掉mainactivity中查询测试数据 的代码

数据库中没有表,是自动生成的那两个数据库文件的原因,删除掉除了.db的另外两个数据文件就可以运行了

我整了还大会,也是这个问题的


好帮手慕雪 2019-06-12 17:23:40

你是不是少复制内容了呢,素材中直接提供数据库了呢。

http://img1.sycdn.imooc.com//climg/5d00c48600018ae102960291.jpg

你看这里,对应的地方有没有。祝:学习愉快

  • 提问者 慕的地6218116 #1
    有的,根据 menu.db 生成了 imooc_menu.db,用数据库管理工具查看 imooc_menu.db 也是有 dish_tb 的,但是代码却报错。 我运行的是模拟器
    2019-06-12 17:27:47
  • 好帮手慕雪 回复 提问者 慕的地6218116 #2
    模拟器也生成数据库了,并且也有对就表?那就奇怪了,应该是模拟器的问题,你试一下真机。
    2019-06-12 17:55:37
好帮手慕雪 2019-06-11 10:00:54

你把这个module导到环境中,直接运行试一下。不要直接用那个APK,这个APK也有可能并不是最终的版本。

  • 提问者 慕的地6218116 #1
    我是自己新建一个项目,然后把下载下来的素材中的 main 文件夹替换新建项目的文件夹,再运行的
    2019-06-12 16:16:53
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师