I am following a video tutorial on Udemy.com from here
Everything has gone well up until messing with SQL. Now, I'm not a total SQL newbie, I actually took a college course on it using SQL from the command line, but I'm not a pro either. The app does not error out when compiled, but gives an immediate force close, and my logcat points me to lvCountries.setAdapter(adapter). The part that interests me is "Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference". So would my adapter be the null object, or lvCountries? My last lead is when I instantiate countries with db.query(). Android Studio gives me a warning saying that it might produce a NullPointerExecption. Thanks to everyone in advance.
01-15 08:39:59.560 9056-9056/com.example.sql E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.sql, PID: 9056
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sql/com.example.sql.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.sql.MainActivity.onCreate(MainActivity.java:44)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
MainActivity.java
package com.example.sql;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends ActionBarActivity {
private CountryDB countryDatabase = null;
private Cursor countries = null;
private ListView lvCountries = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Create the database helper
SQLiteDatabase.CursorFactory factory = null;
countryDatabase = new CountryDB(this, "countryDB", factory);
String[] columnNames = {"Name", "Pop", "Area", BaseColumns._ID};
lvCountries = (ListView) findViewById(R.id.lvCountries);
int[] targetLayoutIDs = {R.id.textName, R.id.textPop, R.id.textArea};
SQLiteDatabase db = countryDatabase.getReadableDatabase();
countries = db.query("countries", columnNames, null, null, null, null, null);
CursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.country_item,
countries, columnNames, targetLayoutIDs, 0);
lvCountries.setAdapter(adapter);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
public void onPause() {
super.onPause();
countryDatabase.close();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
country_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/textName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:id="@+id/subItem"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/popLabel" />
<TextView
android:id="@+id/textPop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:layout_width= "5dp"
android:layout_height="wrap_content"
android:text="@string/space" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/areaLabel" />
<TextView
android:id="@+id/textArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:layout_width= "5dp"
android:layout_height="wrap_content"
android:text="@string/space" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/areaDescriptor" />
</LinearLayout>
</LinearLayout>
Here is the rest of my code in Android Studio format if you're interested. http://www.mediafire.com/download/zu0x71ysl67b779/SQLLiteAndListViews.tar.gz
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
Apparently, lvCountries
is null
which is why this line is crashing:
lvCountries.setAdapter(adapter);
Looking in your code, it seems that you are not retrieving the correct view:
lvCountries = (ListView) findViewById(R.id.lvCountries);
Make sure that there exists a ListView
in your R.layout.activity_main
with
<ListView
android:id="@+id/lvCountries"
... other parameters here
/>