问题
I'm building a simple multi-activity list app to practice with SQLite. I was trying to get the strings from the database to display in the listview
when this started. I'm getting the error
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
Here the code
public class MainActivity extends AppCompatActivity {
SharedPreferences sharedPreferences;
ArrayList<String> listItem;
ArrayAdapter adapter;
ListView lv = (ListView) findViewById(R.id.list_view);
DatabaseHelper db = new DatabaseHelper(this);
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listItem = new ArrayList<>();
viewData();
context = this;
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, textInput.class));
}
});
}
// cast from sql database to the listview
private void viewData() {
Cursor res = db.viewData();
if (res.getCount() == 0 ){
Toast.makeText(this,"No Data!",Toast.LENGTH_SHORT).show();
}
else{
while (res.moveToNext()){
listItem.add(res.getString(1));
}
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,listItem);
lv.setAdapter(adapter);
}
}
}
This is the Database Helper:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "item.db";
public static final String TABLE_NAME = "item_table";
public static final String ID = "item_id";
public static final String NAME = "item_name";
public static final String PRICE = "item_price";
public static final String URL = "item_url";
public DatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME +" ( item_id INTEGER PRIMARY
KEY AUTOINCREMENT,item_name TEXT,item_price INTEGER,item_url TEXT) ");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String name, String price, String url){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(NAME, name);
contentValues.put(PRICE, price);
contentValues.put(URL, url);
long result = db.insert(TABLE_NAME,null,contentValues);
if(result == -1)
return false;
else
return true;
}
public Cursor viewData(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select * from "+TABLE_NAME,null);
return res;
}
This is the textInput Activity
public class textInput extends AppCompatActivity {
SharedPreferences sharedPreferences;
// Editor editor;
// Context _context;
// int PRIVATE_MODE = 0;
// private static final String PREF_NAME = "Items";
// public static final String NAME_LIST = "name";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_input);
//DatabaseHelper db;
//return's to main activity on press
Button addButton = (Button) findViewById(R.id.addButton);
final EditText name = (EditText) findViewById(R.id.itemName);
final EditText url = (EditText) findViewById(R.id.itemURL);
final EditText price = (EditText) findViewById(R.id.itemPrice);
// final SharedPreferences sharedPreferences =
getApplicationContext().getSharedPreferences("items", 0);
final DatabaseHelper db = new DatabaseHelper(this);
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Checks to make sure that all fields are filled out, if yes
then returns to MainActivity
if (name.length() != 0 && price.length() != 0 && url.length()
!=0){
boolean isInserted =
db.insertData(name.getText().toString(),
price.getText().toString(),
url.getText().toString());
if(isInserted == true)
Toast.makeText(textInput.this, "New Item Added",
Toast.LENGTH_SHORT).show();
else
Toast.makeText(textInput.this, "Failed to Add",
Toast.LENGTH_SHORT).show();
//The graphic and the return to MainActivity
Intent returnToMain = new Intent(getApplicationContext(),
MainActivity.class);
startActivity(returnToMain);
}
else{
Toast.makeText(textInput.this, "Please fill out all
fields!", Toast.LENGTH_SHORT).show();
}
}
});
Debug (Error?) Log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.xmaswishlist, PID: 25470
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.xmaswishlist/com.example.xmaswishlist.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2841)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:163)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
at android.content.Context.obtainStyledAttributes(Context.java:655)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:692)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:479)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:214)
at com.example.xmaswishlist.MainActivity.<init>(MainActivity.java:36)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1180)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2831)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
I have tried to fix this using the following:
- Android studio “ Attempt to invoke virtual method android.database.Cursor on a null object reference” problem
- Database error: Attempt to invoke virtual method 'Cursor .getScene()' on a null object reference
- 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference when notify notification Android
回答1:
You try to get view before setting the content in setContentView
, which cause the exception
. Instantiate ListView
and DatabaseHelper
inside onCreate
.
ListView lv;
DatabaseHelper db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
lv = (ListView) findViewById(R.id.list_view);
db = new DatabaseHelper(this);
...
}
回答2:
From the stack trace:
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:214) at com.example.xmaswishlist.MainActivity.(MainActivity.java:36)
In the MainActivity
class you need to move the assignment on this line ListView lv = (ListView) findViewById(R.id.list_view);
into onCreate
. So define the variable where it already is, but move the = (ListView)...
into onCreate
.
findViewById
is being invoked when the class is instantiated, and before onCreate
is called, thus the internal workings are blowing up because the activity itself is not yet initialized.
You'll also need to initialize the database helper in onCreate
.
来源:https://stackoverflow.com/questions/59122158/database-error-nullpointerexception-attempt-to-invoke-virtual-method-getappli