Fatih Aktepe Fatih Aktepe - 4 months ago 38
JSON Question

Android Async JsonTask Error

I'm trying to receive json from an URL. After I got the object I'll parse it and load it on a listview in my App. I'm using Adapter to create the list view and running my jsonTask on my mainActivity then pass the result to adapter. It always throws null pointer exception. Is there a better way to do that? I'm new to android and json task runs as async how can I make my UI load to wait for the result of jsonTask.Here is my code;

Main Activity;

public class TvActivity extends Activity {
ListView lv;
ArrayList<TV> tvList;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
new JSONTask().execute();
lv = (ListView) findViewById(R.id.listView);
lv.setAdapter(new Adapter(this, tvList));

}
}

public class JSONTask extends AsyncTask<String, String, JSONArray> {
ProgressDialog pDialog;

@Override
protected JSONArray doInBackground(String... params) {
return Utility.getJSONArray(Constants.TV_JSON_URL);
}

@Override
protected void onPostExecute(JSONArray result) {
pDialog.dismiss();

for (int i = 0; i < result.length(); i++) {
try {
JSONObject row = result.getJSONObject(i);
String title = row.getString(Constants.TV_TITLE);
String code = row.getString(Constants.TV_CODE);
String image_url = row.getString(Constants.TV_IMAGE_URL);
tvList.add(new TV(title, image_url, code));

} catch (JSONException e) {
e.printStackTrace();

}

}
}
}


My Adapter;

public class TvAdapter extends BaseAdapter {

String[] result;
Context context;
ArrayList<TV> tvArrayList;
int[] imageId;
private static LayoutInflater inflater = null;

public TvAdapter(TvActivity mainActivity, ArrayList<TV> tvList) {
// TODO Auto-generated constructor stub
//result = prgmNameList;
context = mainActivity;
tvArrayList = tvList;
//imageId = prgmImages;
inflater = (LayoutInflater) context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return tvArrayList.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return tvArrayList.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

public class Holder {
TextView tv;
ImageView img;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
TV tvItem = (TV) getItem(position);

Holder holder = new Holder();
View rowView;
rowView = inflater.inflate(R.layout.tv_list, null);
holder.tv = (TextView) rowView.findViewById(R.id.textView1);
holder.img = (ImageView) rowView.findViewById(R.id.imageView1);
holder.tv.setText(tvItem.getTitle());
// holder.img.setImageResource(imageId[position]);
rowView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, "You Clicked " + tvItem[position], Toast.LENGTH_LONG).show();
}
});
return rowView;
}

}

Answer

You may try like below:

new JSONTask().execute();
lv = (ListView) findViewById(R.id.listView);
tvList = new ArrayList<TV>();
lv.setAdapter(new Adapter(this, tvList));

Then

@Override
protected void onPreExecute() {
    super.onPreExecute();
    pDialog = new ProgressDialog(context);
    pDialog.setCancelable(true);
    pDialog.setMessage("Loading...");
    pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    pDialog.setProgress(0);
    pDialog.show();
}

add adapter.notifyDataSetChanged(); below of your onPostExecute method