【问题标题】:Slow Performance of Complex Operations复杂操作性能缓慢
【发布时间】:2013-08-03 21:18:59
【问题描述】:

伙计们。

我设计了一个货币兑换应用程序,在该应用程序中,我在应用程序启动时获得所有汇率并创建自己的 SQLite 数据库,然后轻松地将它们拉入转换器界面。我已经设计了要在带有 textwatcher 的 Edittext onTextChanged 侦听器中完成的更改,并且一切正常。我在同一个活动中也有一个列表视图,用于收藏汇率,并且每次编辑文本更改时也必须计算它。我的主要问题是我的应用程序性能缓慢并出现冻结问题。我试图实现 Asynctask 来处理计算,但它没有帮助我,我仍然遇到性能问题。下面我的代码供您参考。请指教!!

文本观察器:

valval.addTextChangedListener(new TextWatcher() {

        public void onTextChanged(CharSequence s, int start, int before,
                int count) {



        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

        }

        public void afterTextChanged(final Editable s)

        {

            Calculate();

        }
    });

计算:

private void Calculate()

{

    curs = mDb.query(MyDbHelper.TABLE_NAME, columns, MyDbHelper.COL_Common
            + "=" + "?", new String[] { From[xxxto] + From[xxxfrom] },
            null, null, null);
    cursD = mDb.query(MyDbHelper.TABLE_NAME, columns, MyDbHelper.COL_Common
            + "=" + "?", new String[] { From[xxxfrom] + From[xxxto] },
            null, null, null);

    curs.moveToFirst();

    cursD.moveToFirst();

    double selection = curs.getDouble(curs
            .getColumnIndex(MyDbHelper.COL_Currone));

    double selection2 = cursD.getDouble(cursD
            .getColumnIndex(MyDbHelper.COL_Currone));

    Long myNum = Long.parseLong(valval.getText().toString().trim());

    double myNum3 = Double.parseDouble(new DecimalFormat("#.######").format(myNum * selection2));


    valval2.setText(String.valueOf(myNum3));



    Cursor B = mDb.query(MyDbHelper.TABLE_NAME, columns,
            MyDbHelper.COL_CurrFavor + " LIKE ? And "
                    + MyDbHelper.COL_Currsecond + " LIKE ?", new String[] {
                    "YES", "EUR" }, null, null, null);


    for (int s = 0; s < B.getCount() - 1; s++)

    {
        B.moveToPosition(s);

        String ZVZV = B.getString(0);

        int BSBS = B.getInt(9);


        Cursor curcur = mDb.query(MyDbHelper.TABLE_NAME, columns, MyDbHelper.COL_Common
                + "=" + "?", new String[] { From[xxxfrom] + From[BSBS-1] },
                null, null, null);

        curcur.moveToFirst();

        double calcal = curcur.getDouble(6);



        ContentValues args = new ContentValues();

        double formattedNumber = Double.parseDouble(new DecimalFormat("#.######").format(myNum * calcal));

        args.put(MyDbHelper.COL_Currsum,formattedNumber );

        mDb.update(MyDbHelper.TABLE_NAME, args, "_id =" + ZVZV, null);



    }

    cursm.requery();

}

【问题讨论】:

  • 您真的需要为此使用数据库吗?我相信 SQL 专家会告诉您,您的查询效率低下,但为什么不使用共享首选项呢?
  • 因为根据汇率,我的数据库中有大约 4700 行,而且我认为我在共享偏好部分没有这样的经验。任何帮助将不胜感激!
  • 你能把它分解一下吗? 470 种货币和每种 10 个条目或 47 种货币和每种 100 项?是否有其他应用使用您的数据库?
  • 我会尝试找到一种方法来做到这一点,并且我的数据库不会与任何其他应用程序共享。
  • 我只是想了解您的数据结构。基本上,我会认真考虑使用数组来执行此操作,如果您需要在活动之间共享数据,则使用共享首选项(使用简单)。正如我所说,数据库专家可能会告诉您如何改进您的查询 - 在没有专业知识的情况下 - 将您的查询分成更简单的查询,您可能能够自己发现问题。

标签: android sqlite listview android-asynctask


【解决方案1】:

从您的描述中我可以想象到,您很可能有 2 个 EditTexts,其中用户只输入第一个,然后您将同步转换后的值,这是真的吗?如果是,我是否建议您不要在每次更改文本后立即执行该操作?

您可能只想在用户完成输入后才做Calculate(),也许延迟一秒的计算是可以接受的?

// Declare these as class variable
private Handler handler = new Handler();
private Runnable calculateRunnable = new Runnable() {
    public void run() {
        Calculate();
    }
}

至于你的 TextWatcher,改变这个

public void afterTextChanged(final Editable s) {
    handler.removeCallbacks(calculateRunnable);
    handler.postDelayed(calculateRunnable, 1000);
}

【讨论】:

  • 感谢 Chor 的建议,它非常有用。我认为我的复杂操作是从定义“Cursor B”开始直到结束。我已将它们标记为 /* 并发现所有其他事务都非常好,性能也很好。我想我应该看看它。
  • 通常 db 写入操作(磁盘 IO)会花费你相当多的处理资源,更不用说你似乎在每次文本更改时都这样做,最小化更新应该会给你更好的响应能力
猜你喜欢
  • 2019-09-27
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2015-01-27
  • 2021-06-04
  • 2016-11-09
相关资源
最近更新 更多