如何将数据从okhttp和Asynctask放到RecyclerView中

时间:2017-08-25 08:44:22

标签: android android-asynctask android-recyclerview okhttp

我通过okhttp从服务器获取了一些Json数据,我希望在  使用自定义适配器在片段内部的recycleview并收到以下错误。

当我运行此代码时,logcat告诉我以下信息:

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

我在logcat中打印列表,它显示为null。 但是我可以从IE获得一些json数据。有人帮我吗?

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();
        }
    }

}

}

3 个答案:

答案 0 :(得分:0)

当您通过适配器构造函数传递列表时,您的列表处于空状态,因此列表上的任何操作都返回null。

您可以在okhttp请求中添加回调并在响应上构建适配器吗?虽然您需要更新列表,然后才能对其执行任何操作。

答案 1 :(得分:0)

我将以下代码放入方法onPostExecute,它有效。但我认为这不是一个正确的解决方案。就像这样:

     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);

    }

答案 2 :(得分:0)

确保初始化适配器,适配器的数组列表以及将适配器附加到onCreate中的回收器 然后,您必须添加新的yourAsyncTask()。执行需要http呼叫的位置。 在onBackground向数组列表中添加项目,在postExecute中,只需调用通知数据更改方法