2

I've get some Json data from server by okhttp ,and I want to show them in a recycleview inside of a fragment using a custom adapter and receiving the following error.

when I run this code,the logcat tell me the followeing msg:

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference

I print the list in the logcat ,it shows null. but I can get some json data from the IE.Do anyone help me,please?

public class customer extends AppCompatActivity {

private static final String TAG = "MyDebug______ " ;
private RecyclerView cutomerRecyclerView;
private customerAdapter mAdapter;
private ArrayList<custModal> list;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_customer);
    Toolbar toolbar = (Toolbar)findViewById(R.id.custom_toolbar);
    setSupportActionBar(toolbar);

    new getHttpData().execute();
    Log.d(TAG, "the list is :" +list);
     mAdapter = new customerAdapter(this,list);
    cutomerRecyclerView = (RecyclerView)findViewById(R.id.customer_list);
    cutomerRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    cutomerRecyclerView.setAdapter(mAdapter);
    cutomerRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration(){
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state){
            super.onDraw(c,parent,state);
            c.drawColor(R.color.colorDevider);
        }
        @Override
        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
        }
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);

            outRect.offset(0,1);
        }
    });
}


public class customerAdapter extends RecyclerView.Adapter<customerAdapter.customerViewHolder>{
    private Context mcontext;
    private ArrayList<custModal> mlist;
   // private LayoutInflater inflater;
    class customerViewHolder extends RecyclerView.ViewHolder{
        private TextView name,mem,cust_id;

        public customerViewHolder(View view){
            super(view);
            cust_id = (TextView )view.findViewById(R.id.cust_id);
            name = (TextView)view.findViewById(R.id.cust_name);
            mem = (TextView)view.findViewById(R.id.cust_mem);
        }
    }
    public customerAdapter(Context context,ArrayList<custModal> list){
        this.mcontext = context;
        this.mlist = list;
    }
   @Override
   public customerViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
       customerViewHolder holder = new customerViewHolder(LayoutInflater.from(
               customer.this).inflate(R.layout.customer_item,parent,false));
       return holder;
   }
    @Override
    public void onBindViewHolder(customerViewHolder holder,int position){
        holder.cust_id.setText(mlist.get(position).getId());
        holder.name.setText(mlist.get(position).getName());
        holder.mem.setText(mlist.get(position).getMobiphone());
    }
    @Override
    public int getItemCount(){ return mlist.size();}


}

class custModal {

    private String id;
    private String name;
    private String gender;
    private String mobiphone;
    private String creat_time;
    public void setId(String id) {
        this.id = id;
    }
    public String getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
    public String getGender() {
        return gender;
    }

    public void setMobiphone(String mobiphone) {
        this.mobiphone = mobiphone;
    }
    public String getMobiphone() {
        return mobiphone;
    }

    public void setCreat_time(String creat_time) {
        this.creat_time = creat_time;
    }
    public String getCreat_time() {
        return creat_time;
    }

}



public class getHttpData extends AsyncTask<String,Integer,ArrayList<custModal> >{
    //private ArrayList<custModal> custlist;

    @Override

   // protected void onPreExecute(){}

    @Override

    protected ArrayList<custModal> doInBackground(String... params){
        String url = "http://aaaa.bbbbb.cn/index.php/mobi/customer/app_getlist";

        try{
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url(url)
                    .build();
            Response response = client.newCall(request).execute();
            String responseData = response.body().string();
            Log.d(TAG, "doInBackground: "+ responseData);
            if(responseData != null){
                //return getCustFromJson(responseData);
                Gson gson = new Gson();
                ArrayList<custModal> custlist = gson.fromJson(responseData,
                        new TypeToken<List<custModal>>() {}.getType()
                );

                return custlist;
            }else{
                return null;
            }
        }catch (IOException I){
            I.printStackTrace();
        }

        return null;
    }
    @Override

    protected  void onPostExecute(ArrayList<custModal> custlist){
        if(!custlist.isEmpty()){
            super.onPostExecute(custlist);
            list = custlist;
            mAdapter.notifyDataSetChanged();
        }
    }

}

}

Adil Saiyad
  • 1,582
  • 2
  • 17
  • 34
Ethan Wang
  • 23
  • 5

3 Answers3

0

Your list is in a null state when you pass it via adapter constructor therefore any operations on the list return null.

You could add a callback to your okhttp request and construct the adapter on the response? One way or another though you need to update the list before you can perform any operations on it.

GordonW
  • 1,120
  • 2
  • 16
  • 36
0

I put the following code into the Method onPostExecute,it worked.But I think it is not a right solution.like this:

     protected  void onPostExecute(ArrayList<custModal> custlist){
        Log.d(TAG, "onPostExecute(Result result) called");
        Log.d(TAG, "onPostExecute: "+custlist);
        mAdapter = new customerAdapter(customer.this,custlist);
        cutomerRecyclerView = (RecyclerView)findViewById(R.id.customer_list);
        cutomerRecyclerView.setLayoutManager(new LinearLayoutManager(customer.this));
        cutomerRecyclerView.setAdapter(mAdapter);

    }
Ethan Wang
  • 23
  • 5
0

make sure initialize adapter, array list of adapter and attaching adapter to recycler in onCreate You have to then add the new yourAsyncTask().execute where you need to to http call. In your onBackground add items to the array list and in postExecute simply call notify data change method

Umar Hussain
  • 3,461
  • 1
  • 16
  • 38