android – 使用不同的上下文访问数据库

android – 使用不同的上下文访问数据库,第1张

概述我正在摆弄 Android中的数据库访问,看看如何处理事情. 我在MainActivity.java文件中有以下代码: Log.v("test db acc", "start getApplicationContext test");FileDbHelper dbHelper1 = new FileDbHelper(getApplicationContext());SQLiteDatabase 我正在摆弄 Android中的数据库访问,看看如何处理事情.

我在MainActivity.java文件中有以下代码:

Log.v("test db acc","start getApplicationContext test");fileDbHelper dbHelper1 = new fileDbHelper(getApplicationContext());sqliteDatabase db1 = dbHelper1.getWritableDatabase();Log.v("test db acc","success getApplicationContext test");Log.v("test db acc","start getContext test");fileProvIDer provIDer = new fileProvIDer();provIDer.testdbaccess();Log.v("test db acc","success getContext test");

这是provIDer.testdbaccess()函数的定义:

fileDbHelper dbHelper2 = new fileDbHelper(getContext());sqliteDatabase db2 = dbHelper2.getWritableDatabase();

尝试访问数据库的第一次尝试成功,没有任何错误.如果它不存在,它会创建数据库,并且我可以在创建db1对象后查询和写入数据.

当我尝试使用带有getContext()返回的Context来获取可写数据库时,它只会因NullPointerException而失败.它甚至没有开始创建数据库.即使我删除了getApplicationContext()测试行的代码,也会出现症状.

这里的问题是,我正在尝试编写代码以从fileProvIDer中的数据库获取查询,并且我无法从该文件访问getApplicationContext()(它只会引发编译器错误).

如果我在MainActivity.java文件中完成所有进程,那么我没有错误(我知道这不好,我只是出于测试目的).

我的问题是:

>我应该如何以及在哪种上下文中创建数据库?
>为什么我不能使用fileProvIDer中的getApplicationContext()?
>我可以从其创建的其他上下文中访问数据库吗?据我所知,sqlite数据库只是在app自己的文件夹中的androID文件系统中创建的文件.不同的上下文有什么区别?
>为什么我不能在fileProvIDer.java中使用getContext()返回的Context创建数据库?

– 编辑 –

这是错误的logcat:

08-02 16:03:55.628 7614-7614/com.permasse.apps.file.androID E/AndroIDRuntime: FATAL EXCEPTION: main            java.lang.RuntimeException: Unable to resume activity {com.permasse.apps.file.androID/com.permasse.apps.file.androID.MainActivity}: java.lang.NullPointerException                at androID.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)                at androID.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)                at androID.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)                at androID.app.ActivityThread.access0(ActivityThread.java:130)                at androID.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)                at androID.os.Handler.dispatchMessage(Handler.java:99)                at androID.os.Looper.loop(Looper.java:137)                at androID.app.ActivityThread.main(ActivityThread.java:4745)                at java.lang.reflect.Method.invokeNative(Native Method)                at java.lang.reflect.Method.invoke(Method.java:511)                at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)                at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:553)                at dalvik.system.NativeStart.main(Native Method)             Caused by: java.lang.NullPointerException                at com.permasse.apps.file.androID.fileProvIDer.testdbaccess(fileProvIDer.java:120)                at com.permasse.apps.file.androID.MainActivity.onResume(MainActivity.java:32)                at androID.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)                at androID.app.Activity.performResume(Activity.java:5082)                at androID.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)                at androID.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)                 at androID.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)                 at androID.app.ActivityThread.access0(ActivityThread.java:130)                 at androID.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)                 at androID.os.Handler.dispatchMessage(Handler.java:99)                 at androID.os.Looper.loop(Looper.java:137)                 at androID.app.ActivityThread.main(ActivityThread.java:4745)                 at java.lang.reflect.Method.invokeNative(Native Method)                 at java.lang.reflect.Method.invoke(Method.java:511)                 at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)                 at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:553)                 at dalvik.system.NativeStart.main(Native Method) 

这是fileProvIDer.java的相关部分.原始代码包括查询构建器,uri匹配器等.我已经简化了代码以隔离问题.

public class fileProvIDer extends ContentProvIDer {    private fileDbHelper dbHelper;    @OverrIDe    public boolean onCreate() {        dbHelper = new fileDbHelper(getContext());        return true;    }    public voID testdbaccess() {        sqliteDatabase db = dbHelper.getWritableDatabase(); //line no 120    }}

和MainActivity.java

public class MainActivity extends AppCompatActivity{    @OverrIDe    protected voID onResume() {        super.onResume();        fileProvIDer provIDer = new fileProvIDer();        provIDer.testdbaccess(); //line no 32    }}
解决方法 虽然我不确定它为什么会这样,但我解决了这个问题.

在我的fileProvIDer类(扩展ContentProvIDer)中,如果我尝试在除了onCreate()方法之外的其他地方使用getContext(),我会得到一个空的上下文.这就是为什么在我的testdbaccess()方法上获取db引用失败的原因.

我做的是我在fileProvIDer类中声明了一个静态fileDbHelper(它扩展了sqliteOpenHelper).然后在onCreate()方法中,我使用适当的上下文创建了fileDbHelper类.由于它是静态的,我现在可以稍后在同一个类的任何地方使用此对象.现在看起来有点像这样:

public class fileProvIDer extends ContentProvIDer {    // Create static fileDbHelper    private static fileDbHelper dbHelper;    @OverrIDe    public boolean onCreate() {        // We can only access the context from onCreate() function,so we         // instantiate it here to use later on.         dbHelper = new fileDbHelper(this.getContext().getApplicationContext);        // important explanation about context in bottom of the answer!!        return true;    }    // Then I can use it like this:     public voID testdbaccess() {        // dbHelper was staticly declared within class and instantiated already        sqliteDatabase db = dbHelper.getWritableDatabase();         // Then do whatever you want to do with the code    }}

这也回答了我的问题:

我应该如何以及在哪种上下文中创建数据库?

>在创建数据库的上下文中无关紧要,只要您可以获得正确的上下文,就可以访问它.

为什么我不能使用fileProvIDer中的getApplicationContext()?

>事实证明我可以.这样做的正确方法是getContext().getApplicationContext(),但您不必这样做以获取对db的引用.

我可以从创建它的另一个上下文访问数据库吗?

>是的,您可以在getApplicationContext()中创建db并在getContext()中访问它

为什么我不能使用getContext()上下文在fileProvIDer.java文件中创建数据库?

>实际上你可以,问题基本上是因为无法从我编写的新测试函数访问上下文本身.不知道为什么,但这是情况:)

希望以后能帮助别人.

UPDATE

有关静态对象和内存泄漏的重要信息.

m0skit0警告我内存泄漏是由静态对象引起的,这些静态对象持有对上下文的引用.详细信息可以在here找到.简而言之,它说

If you plan on keePing long-lived objects that need a context,
remember the application object. You can obtain it easily by calling
Context.getApplicationContext() or Activity.getApplication().

所以要小心那个.代码段相应更新.这让我从未来的头痛中解脱了很多:)

总结

以上是内存溢出为你收集整理的android – 使用不同的上下文访问数据库全部内容,希望文章能够帮你解决android – 使用不同的上下文访问数据库所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1128116.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-30
下一篇2022-05-30

发表评论

登录后才能评论

评论列表(0条)

    保存