
我在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 – 使用不同的上下文访问数据库所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)