【发布时间】:2022-01-16 08:37:35
【问题描述】:
我收到此错误:
引起:java.lang.NumberFormatException:对于输入字符串:“pets”,同时尝试将数据插入数据库。在单击 mainActivity 上的插入选项时,它应该将数据插入数据库并将该数据显示到 MainActivity 但由于我的应用程序崩溃的错误。如何解决这个错误?该错误是在 PetProvider 查询的 Pet_ID 在选择 args 点处引起的。
PetProvider的代码如下:
`2021-12-12 02:21:07.435 11934-11959/com.example.myapplication E/AndroidRuntime:致命异常:AsyncTask #1
进程:com.example.myapplication,PID:11934java.lang.RuntimeException:执行doInBackground()时出错
在 android.os.AsyncTask$4.done(AsyncTask.java:415)
在 java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
在 java.util.concurrent.FutureTask.setException(FutureTask.java:252)
在 java.util.concurrent.FutureTask.run(FutureTask.java:271)
在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
在 java.lang.Thread.run(Thread.java:923)原因:java.lang.NumberFormatException:对于输入字符串:“pets”
在 java.lang.Long.parseLong(Long.java:594)
在 java.lang.Long.parseLong(Long.java:636)
在 android.content.ContentUris.parseId(ContentUris.java:89)
在 com.example.myapplication.data.PetProvider.query(PetProvider.java:100)
在 android.content.ContentProvider.query(ContentProvider.java:1379)
在 android.content.ContentProvider.query(ContentProvider.java:1475)
在 android.content.ContentProvider$Transport.query(ContentProvider.java:278)
在 android.content.ContentResolver.query(ContentResolver.java:1185)
在 android.content.ContentResolver.query(ContentResolver.java:1116)
在 android.content.CursorLoader.loadInBackground(CursorLoader.java:71)
在 android.content.CursorLoader.loadInBackground(CursorLoader.java:46)
在 android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:321) 在 android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:74) 在 android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:62) 在 android.os.AsyncTask$3.call(AsyncTask.java:394) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 在 java.lang.Thread.run(Thread.java:923)package com.example.myapplication.data;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.nio.file.Path;
public class PetProvider extends ContentProvider {
private PetdbHepler petdbHepler;
public static String CONTENT_AUTHORITY = "com.example.myapplication";
//To make this a usable URI, we use the parse method which takes in a URI string and returns a Uri.
public static Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
//This constants stores the path for each of the tables which will be appended to the base content URI.
public static final String PATH_PETS = "pets";
public static final String LOG_TAG = PetProvider.class.getSimpleName();
/**
* URI matcher code for the content URI for the pets table
*/
private static final int PETS = 100;
/**
* URI matcher code for the content URI for a single pet in the pets table
*/
private static final int PET_ID = 101;
/**
* UriMatcher object to match a content URI to a corresponding code.
* The input passed into the constructor represents the code to return for the root URI.
* It's common to use NO_MATCH as the input for this case.
*/
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Static initializer. This is run the first time anything is called from this class.
static {
// The calls to addURI() go here, for all of the content URI patterns that the provider
// should recognize. All paths added to the UriMatcher have a corresponding code to return
// when a match is found.
sUriMatcher.addURI(CONTENT_AUTHORITY, PATH_PETS, PETS);
sUriMatcher.addURI(CONTENT_AUTHORITY, PATH_PETS + "/#", PET_ID);
}
@Override
public boolean onCreate() {
petdbHepler = new PetdbHepler(getContext());
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
//steps To follow to query the database
//first we nedd to get access to the database
//second we need to pass the uri and check if the query is for whole table or for a single pet using uri matcher
//atlast we need to switch according to the uri
// so here is our code
SQLiteDatabase database = petdbHepler.getReadableDatabase(); /*since we are only querying the database we need to use
getReadableDatabase and this step is to access the database which is first step*/
Cursor cursor;
int matcher = sUriMatcher.match(uri);//second we need to pass the uri and check if the query is for whole table or for a single pet using uri matcher
switch (matcher) {
case PETS:
cursor = database.query(Petcontract.PetsEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
case PET_ID:
// For the PET_ID code, extract out the ID from the URI.
// For an example URI such as "content://com.example.android.pets/pets/3",
// the selection will be "_id=?" and the selection argument will be a
// String array containing the actual ID of 3 in this case.
//
// For every "?" in the selection, we need to have an element in the selection
// arguments that will fill in the "?". Since we have 1 question mark in the
// selection, we have 1 String in the selection arguments' String array.
selection = Petcontract.PetsEntry._ID + "?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
cursor = database.query(Petcontract.PetsEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
Log.e("PetProvider", "Hereis the problem");
break;
default:
throw new IllegalArgumentException("cannot query unknown uri" + uri);
}
// Set notification URI on the Cursor,
// so we know what content URI the Cursor was created for.
// If the data at this URI changes, then we know we need to update the Cursor
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
final int match = sUriMatcher.match(uri);
switch (match) {
case PETS:
return insertPet(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
private Uri insertPet(Uri uri, ContentValues contentValues){
// Check that the name is not null
String name = contentValues.getAsString(Petcontract.PetsEntry.COLUMN_NAME);
if (name == null) {
throw new IllegalArgumentException("Pet requires a name");
}
// Check that the gender is valid
Integer gender = contentValues.getAsInteger(Petcontract.PetsEntry.COLUMN_GENDER);
if (gender == null) {
throw new IllegalArgumentException("Pet requires valid gender");
}
// If the weight is provided, check that it's greater than or equal to 0 kg
Integer weight = contentValues.getAsInteger(Petcontract.PetsEntry.COLUMN_WEIGHT);
if (weight != null && weight < 0) {
throw new IllegalArgumentException("Pet requires valid weight");
}
SQLiteDatabase sqLiteDatabase = petdbHepler.getWritableDatabase();
long id = sqLiteDatabase.insert(Petcontract.PetsEntry.TABLE_NAME, null, contentValues);
// Notify all listeners that the data has changed for the pet content URI
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(Petcontract.PetsEntry.content_uri, id);
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
// Get writeable database
SQLiteDatabase database =petdbHepler.getWritableDatabase();
int rowsDeleted;
final int match = sUriMatcher.match(uri);
switch (match) {
case PETS:
// Delete all rows that match the selection and selection args
return database.delete(Petcontract.PetsEntry.TABLE_NAME, selection, selectionArgs);
case PET_ID:
// Delete a single row given by the ID in the URI
selection = Petcontract.PetsEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
rowsDeleted = database.delete(Petcontract.PetsEntry.TABLE_NAME, selection, selectionArgs);
// If 1 or more rows were deleted, then notify all listeners that the data at the
// given URI has changed
if (rowsDeleted != 0) {
getContext().getContentResolver().notifyChange(uri, null);
return database.delete(Petcontract.PetsEntry.TABLE_NAME, selection, selectionArgs);
}
else{
return rowsDeleted;
}
default:
throw new IllegalArgumentException("Deletion is not supported for " + uri);
}
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
SQLiteDatabase database = petdbHepler.getWritableDatabase();
int rowsUpdated = database.update(Petcontract.PetsEntry.TABLE_NAME, values, selection, selectionArgs);
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
else
{
return database.update(Petcontract.PetsEntry.TABLE_NAME, values, selection, selectionArgs);
}
}
}`
【问题讨论】:
-
好吧,在您的
query方法中的某个地方,您提供了字符串pets,其中应该是long。你的代码中的100行在哪里? -
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};这是第 100 行
标签: java android android-studio