2015-02-07 57 views
0

我是Android新手,正在制作我的第一个应用程序。我使用契约和辅助类创建了一个SQLite表。这工作正常。然后我将数据库包装在一个ContentProvider中,这似乎也可以正常工作。以下是我实例化SQLiteOpenHelper在我的内容提供商类:SQLiteOpenHelper突然变为空

public boolean onCreate() { 
    mTestDb = new TestDbHelper(getContext()); 
    return true; 
} 

然后我有在MainActivity的onCreate()方法两个辅助方法:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    if (savedInstanceState == null) { 
     getSupportFragmentManager().beginTransaction() 
       .add(R.id.container, new PlaceholderFragment()) 
       .commit(); 
    } 

    provider = new TestProvider(); 
    providerInsert(); 
    providerShow(); 
} 

provider被宣布为一个类变量之前。以下是辅助方法:

public void providerInsert() { 
    ContentValues values = new ContentValues(); 
    values.put(TestContract.FIRST_COLUMN, 3); 
    values.put(TestContract.SECOND_COLUMN, "hello."); 
    final Uri uri = getContentResolver().insert(TestContract.CONTENT_URI, values); 
} 

public void providerShow() { 
    Cursor cursor = provider.query(
      TestContract.CONTENT_URI, 
      new String[] {TestContract._ID, TestContract.FIRST_COLUMN, TestContract.SECOND_COLUMN}, 
      null, 
      null, 
      null 
    ); 
    int id = cursor.getInt(0); 
    int first = cursor.getInt(1); 
    String second = cursor.getString(2); 

    String print = "At column" + id + ": " + first + ", " + second; 

    Toast.makeText(getBaseContext(), print, Toast.LENGTH_LONG) 
      .show(); 
} 

继承人踢球员:providerInsert()工作得很好!我得到的值为url,一切看起来都很棒。然后,它进入providerShow()mTestDb现在突然无效!下面是插入()和查询()方法,为我的内容提供商:

public Uri insert(Uri uri, ContentValues values) { 
    SQLiteDatabase db = mTestDb.getWritableDatabase(); 

    switch(matcher.match(uri)) { 

     case FIRST_CASE: { 
      long id = db.insert(
        TestContract.TABLE_NAME, 
        null, 
        values 
      ); 

      return ContentUris.withAppendedId(TestContract.CONTENT_URI, id); 

     } 

     default: { 
      return null; 
     } 
    } 
} 

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
    SQLiteDatabase db = mTestDb.getReadableDatabase(); 
    Cursor rCursor; 

    switch(matcher.match(uri)) { 

     case FIRST_CASE: { 
      rCursor = db.query(
       TestContract.TABLE_NAME, 
       projection, 
       selection, 
       selectionArgs, 
       null, 
       null, 
       sortOrder 
      ); 
      break; 
     } 

     default: { 
      rCursor = null; 
     } 
    } 

    return rCursor; 
} 

正如我以前说过,mTestDb由代码获取到query()的时间变空。我觉得这只是一个愚蠢的错误,它有一个简单的解决方法,但我已经将代码倒了几个小时无济于事。有人可以帮我吗?

在此先感谢! :)

编辑1 - 这里的TestProvider类:

package com.example.android.testapp.data; 

import android.content.ContentProvider; 
import android.content.ContentUris; 
import android.content.ContentValues; 
import android.content.UriMatcher; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.net.Uri; 

import java.net.URI; 

/** 
* Created by Shubhang on 2/5/2015. 
*/ 
public class TestProvider extends ContentProvider { 
    SQLiteOpenHelper mTestDb = null; 
    private static final int FIRST_CASE = 1; 

private static UriMatcher matcher; 
static { 
    matcher = new UriMatcher(UriMatcher.NO_MATCH); 
    matcher.addURI(TestContract.AUTHORITY, null, FIRST_CASE); 
} 

@Override 
public boolean onCreate() { 
    mTestDb = new TestDbHelper(getContext()); 
    return true; 
} 

@Override 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
    SQLiteDatabase db = mTestDb.getReadableDatabase(); 
    Cursor rCursor; 

    switch(matcher.match(uri)) { 

     case FIRST_CASE: { 
      rCursor = db.query(
       TestContract.TABLE_NAME, 
       projection, 
       selection, 
       selectionArgs, 
       null, 
       null, 
       sortOrder 
      ); 
      break; 
     } 

     default: { 
      rCursor = null; 
     } 
    } 

    return rCursor; 
} 

@Override 
public String getType(Uri uri) { 
    String rUri; 

    switch (matcher.match(uri)) { 
     case FIRST_CASE: { 
      rUri = "vnd.android.cursor.dir/" + TestContract.AUTHORITY; 
     } 

     default : { 
      rUri = null; 
     } 
    } 

    return rUri; 
} 

@Override 
public Uri insert(Uri uri, ContentValues values) { 
    SQLiteDatabase db = mTestDb.getWritableDatabase(); 

    switch(matcher.match(uri)) { 

     case FIRST_CASE: { 
      long id = db.insert(
        TestContract.TABLE_NAME, 
        null, 
        values 
      ); 

      return ContentUris.withAppendedId(TestContract.CONTENT_URI, id); 

     } 

     default: { 
      return null; 
     } 
    } 
} 

@Override 
public int delete(Uri uri, String selection, String[] selectionArgs) { 
    return 0; 
} 

@Override 
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 
    return 0; 
} 

}

编辑2 - 下面是一些记录我加入onCreate()query()insert()方法,分别为:

Log.e(TAG, "onCreate(): " + this.toString()); 

Log.e(TAG, "query(): " + this.toString()); 

Log.e(TAG, "insert(): " + this.toString()); 

以下是logcat中的错误语句:

02-07 14:37:17.367 9488-9488/com.example.android.testapp E/TestProvider: onCreate(): [email protected] 
02-07 14:37:17.453 9488-9488/com.example.android.testapp E/TestProvider﹕ insert(): [email protected] 
02-07 14:37:17.524 9488-9488/com.example.android.testapp E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.testapp/com.example.android.testapp.MainActivity}: java.lang.NullPointerException 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
      at android.app.ActivityThread.access$600(ActivityThread.java:141) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:5041) 
      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:793) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
      at dalvik.system.NativeStart.main(Native Method) 
    Caused by: java.lang.NullPointerException 
      at com.example.android.testapp.data.TestProvider.query(TestProvider.java:38) 
      at com.example.android.testapp.MainActivity.providerShow(MainActivity.java:74) 
      at com.example.android.testapp.MainActivity.onCreate(MainActivity.java:40) 
      at android.app.Activity.performCreate(Activity.java:5104) 
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
            at android.app.ActivityThread.access$600(ActivityThread.java:141) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:137) 
            at android.app.ActivityThread.main(ActivityThread.java:5041) 
            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:793) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
            at dalvik.system.NativeStart.main(Native Method) 

正如你所看到的,我的应用程序甚至没有达到破解前的query()方法。

+0

'providerShow()'中的'provider'是什么?它在哪里宣布? – iRuth 2015-02-07 04:10:45

+0

它是一个“TestProvider”类(它是我的Content Provider类):'TestProvider provider;'。它是在MainActivity的'onCreate()'中实例化的''provider'。 – 2015-02-07 04:12:06

+0

它在MainActivity类头下正确声明:'public class MainActivity extends ActionBarActivity {0} {0} {0} {0} TestProvider provider; // ...}' – 2015-02-07 04:15:18

回答

0

我找到了答案!为了查询TestProvider,我需要在我的providerShow()方法中使用内容解析器。