从数据库中获取列表并在 Listview 中显示需要很长时间

Posted

技术标签:

【中文标题】从数据库中获取列表并在 Listview 中显示需要很长时间【英文标题】:Fetching List from Database and showing in Listview takes very much time 【发布时间】:2016-03-29 15:38:19 【问题描述】:

在我的应用程序中,我在我的数据库中存储了 8 个静态 dns 字段。这只是一个名称值对。单击按钮时,我将存储在数据库中的名称和 IP 地址获取到数组列表中,并使用基本适配器在列表视图中显示它们。一切正常,但按下按钮后几乎需要 4-5 秒才能显示 listview 。 这个时间是正常的还是应该更少?此外,我还从代码的其他部分添加该列表中的项目,因此每次我必须再次从数据库中获取列表时单击按钮。 如果这个时间更多,如果不是,我该怎么做才能减少这个时间??

这是在按钮单击时运行的代码

public void LoadPrimaryDnsList()

    dnsName=dataBaseHelper.getDnsName();
    ipAddress=dataBaseHelper.getIpAddress();
    id=dataBaseHelper.getId();
    dnsListAdapter = new DnsListAdapter(getActivity(), dnsName, ipAddress,id);
    dnsListAdapter.notifyDataSetChanged();
    android.support.v7.app.AlertDialog.Builder builder;
    final android.support.v7.app.AlertDialog alertDialog;
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View layout = inflater.inflate(R.layout.browse_dns_dialog, (ViewGroup) getActivity().findViewById(R.id.lin_dialog));
    listView = (ListView) layout.findViewById(R.id.dns_list);

    builder = new android.support.v7.app.AlertDialog.Builder(getActivity());
    builder.setView(layout);
    alertDialog = builder.create();

    alertDialog.show();
    listView.setAdapter(dnsListAdapter);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
            String ip = ipAddress.get(position);
            EDITDNS1.setText(ip);
            alertDialog.dismiss();
        

    );

这是适配器类

public class DnsListAdapter extends BaseAdapter 
    Context context;

    LayoutInflater layoutInflater;

    ArrayList<String> dnslist=new ArrayList<>();
    ArrayList<String> iplist=new ArrayList<>();
    ArrayList<String> ids=new ArrayList<>();
    public DnsListAdapter(Context context, ArrayList<String> dns, ArrayList<String> ip,ArrayList<String> id) 
        this.context = context;
        dnslist=dns;
        iplist=ip;
        ids=id;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    

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

    @Override
    public Object getItem(int position) 
        return null;
    

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 
        ViewHolder holder = null;
        if (convertView == null) 
            holder = new ViewHolder();
            convertView = layoutInflater.inflate(R.layout.dialog_row, parent, false);
            holder.tv_name = (TextView) convertView.findViewById(R.id.dnsName);
            holder.tv_ip= (TextView) convertView.findViewById(R.id.ip_address);
            holder.iv_cross= (ImageView) convertView.findViewById(R.id.iv_cross);
            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        

        holder.tv_name.setText(dnslist.get(position));
        if (holder.tv_name.getText().toString().equalsIgnoreCase("Google 1")||holder.tv_name.getText().toString().equalsIgnoreCase("Google 2")||holder.tv_name.getText().toString().equalsIgnoreCase("Level3 1")
                ||holder.tv_name.getText().toString().equalsIgnoreCase("Level3 2")||holder.tv_name.getText().toString().equalsIgnoreCase("DNS Watch 1")||holder.tv_name.getText().toString().equalsIgnoreCase("DNS Watch 2")
                ||holder.tv_name.getText().toString().equalsIgnoreCase("OpenDNS 1")||holder.tv_name.getText().toString().equalsIgnoreCase("OpenDNS 2"))
        
            holder.iv_cross.setVisibility(View.INVISIBLE);
        
        holder.tv_ip.setText(iplist.get(position));
        Fonts.setHelveticaFont(getActivity(), holder.tv_name);
        Fonts.setHelveticaFont(getActivity(), holder.tv_ip);
        holder.iv_cross.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                dataBaseHelper.deleteRow(id.get(position));
                dnsName.remove(position);
                ipAddress.remove(position);
                id.remove(position);
                dnsListAdapter.notifyDataSetChanged();

            
        );
        return convertView;
    


【问题讨论】:

使用Cursor loader从后台执行操作的数据库中获取数据。 你能给我例子或链接吗 查看***.com/questions/18326954/… 这就像再次创建完整的应用程序一样,因为我在我的应用程序中多次查询数据库。目前的实现还有其他方法吗?? 【参考方案1】:

我建议您加载数据并使用AsyncTask 异步填充ListView

【讨论】:

这将是一种解决方法,例如在数据加载时显示用户加载。我想知道是我做错了什么还是做这项工作需要这么多时间 这是一种有效的方法。除非您只想使用适配器直接附加某些内容,即 adapter.addItem() 所以这意味着需要这么多时间来获取数据并显示它 试着去掉那个布局膨胀部分,把它变成一个字段,看看它是否加载得更快。 你的方式可以适用于几个项目,但如果它开始增长,你将不得不改变它。尝试删除此行:dnsListAdapter.notifyDataSetChanged(); 看看是否有帮助。【参考方案2】:

如果你想要速度,你应该预先加载所有的东西。

@Override
public void onCreate(Bundle s) 
    dnsName=dataBaseHelper.getDnsName();
    ipAddress=dataBaseHelper.getIpAddress();
    id=dataBaseHelper.getId();
    dnsListAdapter = new DnsListAdapter(getActivity(), dnsName, ipAddress,id);
    dnsListAdapter.notifyDataSetChanged();
    android.support.v7.app.AlertDialog.Builder builder;
    final android.support.v7.app.AlertDialog alertDialog;
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View layout = inflater.inflate(R.layout.browse_dns_dialog, (ViewGroup) getActivity().findViewById(R.id.lin_dialog));
    listView = (ListView) layout.findViewById(R.id.dns_list);

    builder = new android.support.v7.app.AlertDialog.Builder(getActivity());
    builder.setView(layout);
    alertDialog = builder.create();

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
            String ip = ipAddress.get(position);
            EDITDNS1.setText(ip);
            alertDialog.dismiss();
        

    );


public void LoadPrimaryDnsList()
    alertDialog.show();
    listView.setAdapter(dnsListAdapter);

除此之外,如果你想了解你的代码的速度,你应该开始添加一些计时日志http://developer.android.com/reference/android/util/TimingLogger.html

另外,为了使您的代码更具可读性(并且更易于扩展/增强),我将开始了解 Single Responsibility Principle 并将其应用到您的方法中。

【讨论】:

我已经写过,用户可以从另一个位置在数据库中输入行,在这里点击按钮我必须显示更新的数据,所以我想我必须在点击按钮时查询数据库 我们实际上无法从您的代码中看出发生了什么。您所解释的内容与代码不符。 /我还认为您在片段中使用此代码?但是你膨胀一个布局并找到一个关于 Activity 的视图,我认为你需要回去阅读一些 Fragments 的基础知识并学习 Android 生命周期 @VivekMishra 您不必在 onClick 上查询数据库 - 在活动首次加载时读取数据库,然后在内存中存储,例如 Map 并从该 onClick 中读取 我想说的是,我的应用程序中有一个添加按钮,用户可以通过该按钮添加自己的 dns 名称,并且预添加和用户添加的记录都添加到同一个表中,因此我再次获取数据点击以防用户添加了他自己的一些记录

以上是关于从数据库中获取列表并在 Listview 中显示需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”

从数据库中获取照片并在列表视图中显示

显示数据库最后一条数据,首先在listView中

如何在列表视图的每个项目上加载 json 数据并显示在 android 的另一个活动中获取的数据?

通过意图获取数据并将其显示在列表视图中时,应用程序正在停止

如何从 Internet 获取图像并在 ListView 中过去?