2015-02-07 4 views
0

저는 Android가 처음이므로 첫 번째 앱을 제작하고 있습니다. 계약과 도우미 클래스를 사용하여 SQLite 테이블을 만들었습니다. 그건 잘 작동합니다. 그런 다음 ContentProvider에 데이터베이스를 래핑합니다. ContentProvider도 정상적으로 작동합니다.SQLiteOpenHelper가 갑자기 null이됩니다.

@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 boolean onCreate() { 
    mTestDb = new TestDbHelper(getContext()); 
    return true; 
} 

난 후 MainActivity의에서 onCreate() 메소드에 두 개의 헬퍼 메소드를 가지고 : 내 콘텐츠 공급자 클래스의 SQLiteOpenHelper를 인스턴스화하는 방법은 다음과 . 여기에 도우미 방법은 다음과 같습니다

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(); 
} 

을 Heres 키커

: providerInsert() 작품 잘! url에 대한 값을 얻고 있으며 모든 것이 훌륭하게 보입니다. 그런 다음 providerShow()으로 이동하고 mTestDb이 갑자기 null입니다!

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()에 도착하는 시간에 의해 널 (null)이된다 : 여기 내 콘텐츠 제공을위한 인서트()와 쿼리() 메서드입니다. 나는 이것이 바보 같은 오류 인 것처럼 느껴진다. 그리고 그것은 간단한 수정을 가지고있다. 그러나 나는 아무 소용이없는 시간 동안 코드를 쏟아 부었다. 누군가 나를 도울 수 있겠습니까?

미리 감사드립니다. - :

편집 (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

+0

클래스 레벨'TestProvider' (내 컨텐츠 제공자 클래스) :'TestProvider provider;'. MainActivity에서'onCreate()'에서 인스턴스화 한 것과 같은 '제공자'입니다. –

+0

MainActivity 클래스 헤더 바로 아래에 선언되어 있습니다 :'public class MainActivity extends ActionBarActivity { TestProvider provider; // ...}' –

답변

0

답변을 찾았습니다! TestProvider을 쿼리하기 위해 providerShow() 메서드에서 콘텐츠 리졸버를 사용해야했습니다.

관련 문제