尝试通过列表视图显示数据时应用程序崩溃

Posted

技术标签:

【中文标题】尝试通过列表视图显示数据时应用程序崩溃【英文标题】:App get crashed when trying to display Data through listview 【发布时间】:2019-05-08 17:10:57 【问题描述】:

我正在尝试使用 retrofit2 获取数据并使用作为自定义适配器参数传递的列表显示这些数据。当我在onResponse() 方法中的列表中存储数据时,onResponse() 方法中的列表有一些价值。但在oncreate() 方法中,它给我null。不过,我将 List 声明为全局。当我运行应用程序时,有时它什么也不显示,有时应用程序崩溃。我知道这听起来很疯狂。但它正在发生。所以,我想知道,我的代码有什么问题?如何在列表视图中显示数据?

如果我的问题模式有问题,但这是我在这个网站上的第一个问题,请原谅我。

MainActivity`

public class LaboratoryValues extends AppCompatActivity 

    public List<Data> productList = null;
    List<Data>arrayList = null;
    int size;
    String st;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_laboratory_values);

        //productList = new ArrayList<Data>();
        getInvestigation();
        for(int i =0; i < size; i++)

            st = arrayList.get(i).getName();


        
        System.out.println("Name : "+st);//here print Name : null

        ListView lview = (ListView) findViewById(R.id.listview);
        ListviewAdapter adapter = new ListviewAdapter(this, arrayList);
        lview.setAdapter(adapter);



    


    private void getInvestigation() 

       /* final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setCancelable(false); // set cancelable to false
        progressDialog.setMessage("Please Wait"); // set body
        progressDialog.show(); // show progress dialog*/


        ApiInterface apiService =
                Api.getClient(ApiInterface.BASE_URL).create(ApiInterface.class);


        Call<Investigation> investigationCall = apiService.getInvestigation();
        investigationCall.enqueue(new Callback<Investigation>() 
            @Override
            public void onResponse(Call<Investigation> call, Response<Investigation> response) 

                arrayList = response.body().getData();
              //productList.addAll(arrayList);
                size = response.body().getData().size();
                for (int i = 0; i < size; i++) 

                    System.out.println("Name : " + arrayList.get(i).getName());//here printing Name is ok


                

            
            @Override
            public void onFailure(Call<Investigation> call, Throwable t) 
                Toast.makeText(getApplicationContext(),"data list is empty",Toast.LENGTH_LONG).show();

            
        );




    



自定义适配器 (listviewAdapter)

public class ListviewAdapter extends BaseAdapter 


        public List<Data> productList;
        Activity activity;
        //Context mContext;

        public ListviewAdapter(Activity activity, List<Data> productList) 
            super();
            this.activity = activity;
            this.productList = productList;
        

        @Override
        public int getCount() 
            return productList.size();
        

        @Override
        public Object getItem(int position) 
            return productList.get(position);
        

        @Override
        public long getItemId(int position) 
            return position;
        

        private class ViewHolder 
            TextView name;
            TextView normal_finding;
            TextView increased;
            TextView decreased;
            TextView others;
        

        @Override
        public View getView(int position, View convertView, ViewGroup parent) 

            ViewHolder holder;
            LayoutInflater inflater = activity.getLayoutInflater();


            if (convertView == null) 
                convertView = inflater.inflate(R.layout.listview_row, null);
                holder = new ViewHolder();
             holder.name = convertView.findViewById(R.id.name);
             holder.normal_finding =convertView.findViewById(R.id.normal_finding);
             holder.increased = convertView.findViewById(R.id.increased);
             holder.decreased = convertView.findViewById(R.id.decreased);
             holder.others =convertView.findViewById(R.id.others);
             convertView.setTag(holder);
             else 
                holder = (ViewHolder) convertView.getTag();
            

            Data item = productList.get(position) ;
            holder.name.setText(item.getName());
            System.out.println("holderName : "+item.getName() );
            holder.normal_finding.setText(item.getNormal_finding());
            System.out.println("holderName : "+item.getNormal_finding() );
            holder.increased.setText(item.getIncreased());
            holder.decreased.setText(item.getDecreased());
            holder.others.setText(item.getOthers());

            return convertView;


        

    

【问题讨论】:

该改造操作是异步的,这意味着在调用 enqueue() 后您的代码将立即继续执行,并且您可能在实例化并设置 Adapter 之前不会得到响应在ListView。这就是您在日志中获得空值的原因。需要等到onResponse()中获取数据后才能设置Adapter中的数据。 【参考方案1】:

它不起作用是完全正常的。 将您的方法 getInvistigation() 放在循环之前并不意味着您的请求的响应已完成 调用 web 服务会创建另一个线程来等待服务器发送响应,有时响应所需的时间取决于服务器和 Internet 连接的延迟。

您只需在获取数据后将处理(循环和适配器)放在 getInvistagion 中即可。

【讨论】:

以上是关于尝试通过列表视图显示数据时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

与核心数据一起使用时预览崩溃

使用 SwiftUI 时尝试在视图中显示工作表时应用程序崩溃

如何在片段类的列表视图中显示 SQLite 数据库?

滚动表格视图时应用程序崩溃

尝试通过循环动态添加多个文本视图时应用程序崩溃。添加单个文本视图时效果很好

[执行textView命令时应用程序崩溃