I’m still quite new to Android and Java. Was learning about Android Listviews and did so by adapting code from this tutorial: http://w2davids.wordpress.com/android-listview-with-iconsimages-and-sharks-with-lasers/
However, I came into this problem where the java.lang.NullPointerException was thrown when doing stockName.setText(stock.name).
Here are my codes:
Stocks.java
package sg.jon.stocks;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Stocks extends Activity {
static final String STOCK_API_URL = "<removed>";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new UpdateStockData().execute();
}
private class UpdateStockData extends AsyncTask<Void, Integer, JSONObject>{
protected JSONObject doInBackground(Void... params) {
Log.v("stocks", "Starting HTTP request");
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(STOCK_API_URL);
String response = null;
try {
ResponseHandler<String> responseHandler=new BasicResponseHandler();
response = httpclient.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v("stocks", "Finished HTTP request");
Log.v("stocks", "Starting to parse JSON");
JSONObject jsonResult = null;
try {
jsonResult = new JSONObject(response.replace("{}&& ",""));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v("stocks", "JSON parsing complete");
return jsonResult;
}
protected void onPostExecute(JSONObject jsonResult){
String[] stockNames = null;
String[] stockPrices = null;
List<Stock> stocks = null;
String label = null;
try {
// label => As at dd-mm-yyyy h:mm AM/PM
label = jsonResult.getString("label");
JSONArray stocksJSONArray = jsonResult.getJSONArray("items");
stockNames = new String[stocksJSONArray.length()];
stockPrices = new String[stocksJSONArray.length()];
stocks = new ArrayList<Stock>();
for(int i=0; i<stocksJSONArray.length(); i++){
Stock stock = new Stock();
stock.name = stocksJSONArray.getJSONObject(i).getString("N");
stock.price = stocksJSONArray.getJSONObject(i).getString("LT");
stocks.add(stock);
stockNames[i] = stocksJSONArray.getJSONObject(i).getString("N");
stockPrices[i] = stocksJSONArray.getJSONObject(i).getString("LT");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(Stocks.this, label, Toast.LENGTH_LONG).show();
ListView stocksListView = (ListView) findViewById(R.id.stocksListView);
stocksListView.setAdapter(new StockArrayAdapter(
getApplicationContext(), R.layout.list_row, stocks)
);
}
}
public class Stock
{
public String name;
public String price;
public Stock()
{
// TODO Auto-generated constructor stub
}
public Stock(String name, String price)
{
this.name = name;
this.price = price;
}
@Override
public String toString()
{
return this.name;
}
}
public class StockArrayAdapter extends ArrayAdapter<Stock> {
private Context context;
private TextView stockName;
private TextView stockPrice;
private List<Stock> stocks = new ArrayList<Stock>();
public StockArrayAdapter(Context context, int textViewResourceId,
List<Stock> objects) {
super(context, textViewResourceId, objects);
this.context = context;
this.stocks = objects;
}
public int getCount() {
return this.stocks.size();
}
public Stock getItem(int index) {
return this.stocks.get(index);
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
// ROW INFLATION
Log.d("xml", "Starting XML Row Inflation ... ");
LayoutInflater inflater = (LayoutInflater) this.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item, parent, false);
Log.d("xml", "Successfully completed XML Row Inflation!");
}
// Get item
Stock stock = getItem(position);
Log.v("stk",stock.name);
Log.v("stk",stock.price);
stockName = (TextView) row.findViewById(R.id.stockName);
stockPrice = (TextView) row.findViewById(R.id.stockPrice);
stockName.setText(stock.name);
stockPrice.setText(stock.price);
return row;
}
}
}
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/stocksListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:textColor="#fff">
</TextView>
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/stockName"
android:paddingLeft="10dip"
android:layout_weight="0.5"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/stockPrice"
android:layout_gravity="right"
android:paddingRight="10dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
This is the error shown in the logs:
04-30 12:07:16.835: W/dalvikvm(1657): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
04-30 12:07:16.883: E/AndroidRuntime(1657): FATAL EXCEPTION: main
04-30 12:07:16.883: E/AndroidRuntime(1657): java.lang.NullPointerException
04-30 12:07:16.883: E/AndroidRuntime(1657): at sg.jon.stocks.Stocks$StockArrayAdapter.getView(Stocks.java:191)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.AbsListView.obtainView(AbsListView.java:2033)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.ListView.measureHeightOfChildren(ListView.java:1244)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.ListView.onMeasure(ListView.java:1155)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.View.measure(View.java:12723)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.View.measure(View.java:12723)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.View.measure(View.java:12723)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.LinearLayout.measureVertical(LinearLayout.java:812)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.View.measure(View.java:12723)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
04-30 12:07:16.883: E/AndroidRuntime(1657): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2092)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.View.measure(View.java:12723)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1064)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.os.Handler.dispatchMessage(Handler.java:99)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.os.Looper.loop(Looper.java:137)
04-30 12:07:16.883: E/AndroidRuntime(1657): at android.app.ActivityThread.main(ActivityThread.java:4424)
04-30 12:07:16.883: E/AndroidRuntime(1657): at java.lang.reflect.Method.invokeNative(Native Method)
04-30 12:07:16.883: E/AndroidRuntime(1657): at java.lang.reflect.Method.invoke(Method.java:511)
04-30 12:07:16.883: E/AndroidRuntime(1657): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-30 12:07:16.883: E/AndroidRuntime(1657): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-30 12:07:16.883: E/AndroidRuntime(1657): at dalvik.system.NativeStart.main(Native Method)
Thanks (:
Your problem is this line:
You are trying to inflate that line and do this:
However, since neither id exists in that layout, stockName and stockPrice are null, then when you try and use them to set your value you get your NPE.
Change that layout to R.id.list_row and you should be ok.