0

我有一个应用程序,当你加载它时,它会显示 6 个按钮。第 6 个按钮需要可视化一些数据。此数据以 txt 文件JSON格式存储在我的/raw文件夹中。数据大小为 600kb,但目前解析并存储在数据库中大约需要 3 分钟。这个想法是,一旦它在数据库中,读取和使用数据的效率和速度要高得多,而不是每次都直接从文件中读取。

我最初制作了这个应用程序,以便它从我的 REST 服务器下载数据,然后将其存储在数据库中,但后来发现将文件与应用程序一起发送会快得多。但是,它仍然很慢。

我正在寻找有关如何加快此文件解析并使用户体验更好的建议。目前,他们第一次进入此部分时,会ProgressDialog出现 a,他们必须等待几分钟(在我的 HTC Desire 上为 3 分钟)才能完成所有这些文件解析,然后才能使用该功能。进度对话框就在那里,一直工作直到完成,用户无法做任何其他事情。它并不理想!我曾考虑在应用程序启动时在后台的单独线程中运行文件处理,没有进度条,因此它对用户来说似乎是无声的,但是,如果他们选择按钮进入该部分应用程序一加载就依赖这些数据,那么它将导致进一步的问题,因为文件处理可能尚未完成。

也许我可以添加一些带有大量文本的“指导性”弹出框,这样当他们阅读它们时,文件处理就完成了。但是,我不确定为应用程序增加了什么价值。使用起来非常简单!

任何人都可以在这里给我一个更好的策略的建议吗?另外,我是否认为 3 分钟解析 600kb 的 JSON 有点太长了?也许我的逻辑没有应有的效率。

这是线程的开始:

private boolean parseFile() {
    dialog = ProgressDialog.show(activity,
             "Progress Title",
             "Progress body",
             true);
    ReadDataThread unt = new ReadDataThread();
    unt.start();
    return true;
}

private class ReadDataThread extends Thread {
    @Override
    public void run() {
        InputStream is = activity.getResources().openRawResource(R.raw.dbdata);
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        try {
            StringBuilder sb = new StringBuilder();
            sb.append(reader.readLine());
            sortAndStore(sb.toString());
        } catch (IOException e) {
            Log.e(Constants.TAG, "Error reading data");
            e.printStackTrace();
        }
        handler.sendEmptyMessage(0);
    }

    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (dialog.isShowing())
                dialog.dismiss();
            Toast.makeText(activity, "Finished reading data", Toast.LENGTH_SHORT).show();
        }
    };
}

你会注意到它调用了一个名为 的方法sortAndStore,这里是:

@Override
public boolean sortAndStore(String raw) {
    boolean returnCode=false;
    ContentValues initialValues = new ContentValues();

    try {
        JSONObject f = new JSONObject(raw);
        JSONArray jsonArr = f.getJSONArray("stops");
        int arrSize=jsonArr.length();
        for(int i=0; i<arrSize; i++) {              
            initialValues.put("name", jsonArr.getJSONObject(i).getString("name"));
            initialValues.put("lat", jsonArr.getJSONObject(i).getString("lat"));
            initialValues.put("lng", jsonArr.getJSONObject(i).getString("lng"));
            initialValues.put("StopNumber", jsonArr.getJSONObject(i).getString("StopNumber"));
            initialValues.put("Route", jsonArr.getJSONObject(i).getString("Route"));
            initialValues.put("Type", jsonArr.getJSONObject(i).getString("Type"));

            //Add data to DB
            DBHelper db = new DBHelper(activity);
            returnCode = db.addData(initialValues, DBHelper.DBTableName);
        }
    } catch (JSONException e) {
        returnCode=false;
        e.printStackTrace();
    }
    return returnCode;
}

我还使用了一个名为 DatabaseHelper 的类DBHelper来处理数据库内容。方法在DBHelper.addData()这里:

public boolean addData(ContentValues initialValues, String tableName) {
    openDatabase();
    long returnCode = db.insert(tableName, "ID", initialValues);
    closeDatabase();
    return (returnCode == -1 ? false:true);
}

那么,任何人都可以根据上述数据提出更好的策略吗?是更高效的文件 I/O 代码,还是一些 UI 技巧让用户觉得处理时间比实际时间短?

谢谢你。

4

3 回答 3

0

我通过简单地使用statements而不是单独的insert语句来解决这个问题。

例如,在for()循环之前,我得到了数据库并启动了事务。然后我像往常一样通过循环。循环之后,我简单地关闭了事务,从而启用了批量事务。

插入现在只需几秒钟!

于 2013-02-19T15:15:46.370 回答
0

我认为您显示在角落某处的固定区域显示进度,例如操作栏或其他东西等。进度可能会在您的应用程序中全局显示进度。然后用户会知道一些工作正在进行,你可以让用户在没有你的数据的情况下完成一些操作。

于 2013-02-03T14:18:01.677 回答
0

如前所述,您可以使用预填充的数据库发布应用程序。查看这篇文章,它非常简单明了在 Android 应用程序中使用自己的 SQLite 数据库

于 2013-02-03T16:24:15.163 回答