从数据库中获取列表并在 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 服务器“无数据”