我是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()
方法。
'providerShow()'中的'provider'是什么?它在哪里宣布? – iRuth 2015-02-07 04:10:45
它是一个“TestProvider”类(它是我的Content Provider类):'TestProvider provider;'。它是在MainActivity的'onCreate()'中实例化的''provider'。 – 2015-02-07 04:12:06
它在MainActivity类头下正确声明:'public class MainActivity extends ActionBarActivity {0} {0} {0} {0} TestProvider provider; // ...}' – 2015-02-07 04:15:18