I am trying to parse JSON from an URL in a ListView, but it shows an error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.volley.toolbox.ImageLoader com.example.vijaypremi.acmeoopsfood.util.AppController.getImageLoader()' on a null object reference
    at com.example.vijaypremi.acmeoopsfood.adapter.CustomListAdapter.<init>(CustomListAdapter.java:26)
    at com.example.vijaypremi.acmeoopsfood.MainActivity.onCreate(MainActivity.java:44)
    at android.app.Activity.performCreate(Activity.java:5990)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
My Main Activity is :
public class MainActivity extends Activity {
    // Log tag
    private static final String TAG = MainActivity.class.getSimpleName();
    // Billionaires json url
    private static final String url = "http://ibookstay.com/oops/restapi/all-restaurant";
    private ProgressDialog pDialog;
    private List<RestaurentInfo> RestaurentInfoList = new ArrayList<RestaurentInfo>();
    private ListView listView;
    private CustomListAdapter adapter;
    String in;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.list);
        adapter = new CustomListAdapter(this, RestaurentInfoList);
        listView.setAdapter(adapter);
        pDialog = new ProgressDialog(this);
        // Showing progress dialog before making http request
        pDialog.setMessage("Loading...");
        pDialog.show();
        // Creating volley request obj
        final JsonArrayRequest reqqueue = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d(TAG, response.toString());
                        hidePDialog();
                        // Parsing json
                        try {
                            JSONObject  jsonRootObject = new JSONObject(url);
                            //Get the instance of JSONArray that contains JSONObjects
                            JSONArray mainnode =jsonRootObject.getJSONArray("data");
                            //Iterate the jsonArray and print the info of JSONObjects
                            for(int i=0; i < mainnode.length(); i++){
                                JSONObject jsonObject = mainnode.getJSONObject(i);
                                JSONObject data = jsonObject.getJSONObject("restaurentInfo");
                                RestaurentInfo restaurentinfo = new RestaurentInfo();
                                restaurentinfo.setRestaurent_name(data.getString("restaurent_name"));
                                restaurentinfo.setRestaurent_logo(data.getString("restaurent_logo"));
                                restaurentinfo.setRestaurent_phone_number(data.getString("restaurent_phone_number"));
                                restaurentinfo.setRestaurent_bussiness_owner_name(data.getString("restaurent_bussiness_owner_name"));
                                restaurentinfo.setRestaurent_email(data.getString("restaurent_email"));
                            }
                            Log.d(TAG, "onResponse: ");
                        } catch (JSONException e) {e.printStackTrace();}
                        // notifying list adapter about data changes
                        // so that it renders the list view with updated data
                        adapter.notifyDataSetChanged();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                hidePDialog();
            }
        });
        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(reqqueue);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        hidePDialog();
    }
    private void hidePDialog() {
        if (pDialog != null) {
            pDialog.dismiss();
            pDialog = null;
        }
    }
}
And My CustomListAdapter is :
public class CustomListAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<RestaurentInfo> restaurentinfo;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();
    public CustomListAdapter(Activity activity, List<RestaurentInfo> restaurentinfo) {
        this.activity = activity;
        this.restaurentinfo = restaurentinfo;
    }
    @Override
    public int getCount() {
        return restaurentinfo.size();
    }
    @Override
    public Object getItem(int location) {
        return restaurentinfo.get(location);
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_row, null);
        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();
        NetworkImageView thumbNail = (NetworkImageView) convertView
                .findViewById(R.id.thumbnail);
        TextView name = (TextView) convertView.findViewById(R.id.name);
        TextView worth = (TextView) convertView.findViewById(R.id.worth);
        TextView source = (TextView) convertView.findViewById(R.id.source);
        TextView year = (TextView) convertView.findViewById(R.id.inYear);
        // getting billionaires data for the row
        RestaurentInfo m = restaurentinfo.get(position);
        // thumbnail image
        thumbNail.setImageUrl(m.getRestaurent_logo(), imageLoader);
        // name
        name.setText(m.getRestaurent_name());
        // Wealth Source
        source.setText("Wealth Source: " + String.valueOf(m.getRestaurent_info_id()));
        worth.setText(String.valueOf(m.getRestaurent_phone_number()));
        // release year
        year.setText(String.valueOf(m.getRestaurent_email()));
        return convertView;
    }
}
For Request Queue and Image Loader i have created AppController :
public class AppController extends Application {
     public static final String TAG = AppController.class.getSimpleName();
        private RequestQueue mRequestQueue;
        private ImageLoader mImageLoader;
        private static AppController mInstance;
        @Override
        public void onCreate() {
            super.onCreate();
            mInstance = this;
        }
        public static synchronized AppController getInstance() {
            return mInstance;
        }
        public RequestQueue getRequestQueue() {
            if (mRequestQueue == null) {
                mRequestQueue = Volley.newRequestQueue(getApplicationContext());
            }
            return mRequestQueue;
        }
        public ImageLoader getImageLoader() {
            getRequestQueue();
            if (mImageLoader == null) {
                mImageLoader = new ImageLoader(this.mRequestQueue,
                        new LruBitmapCache());
            }
            return this.mImageLoader;
        }
        public <T> void addToRequestQueue(Request<T> req, String tag) {
            // set the default tag if tag is empty
            req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
            getRequestQueue().add(req);
        }
        public <T> void addToRequestQueue(Request<T> req) {
            req.setTag(TAG);
            getRequestQueue().add(req);
        }
        public void cancelPendingRequests(Object tag) {
            if (mRequestQueue != null) {
                mRequestQueue.cancelAll(tag);
            }
        }
    }
 
     
     
    