在插入数据库之前对大量数据进行排序

时间:2013-04-10 20:17:22

标签: android json sqlite gson greendao

我需要下载一个大的json String。我正在使用aQuery。然后我需要在一个对象列表中解析这个字符串(10k +)(我正在使用Gson库)并将此列表插入数据库(使用GreenDAO创建)。但在插入之前,我需要通过我的对象字符串字段对此列表进行排序。我正在使用Collat​​or类进行排序,因为这个文件可能使用不同的语言。问题是:如何使用尽可能少的内存来做这样的事情?

现在我下载一个String(+ String,我也尝试使用Streams)然后解析它(+ List)然后对它进行排序(更多的对象)。我是在一个单独的线程中完成它,但即使它完成了内存未被释放。我认为这可以解决,如果我可以在数据已经存在于数据库中时对其进行排序(而不是在选择时,它会变慢),但我不知道如何。

这是一些代码。 这是从文件加载的数据。从文件加载时内存存在同样的问题,我在使用InputStream而不是将JSON字符串放入内存。

public static void getEnciclopediaDataFromFile() {
    mRequestStates.put("enc", true);

    try {
        EncyclopediaParser parser = new EncyclopediaParser(ResourceManager.getResourceManager().loadFile("enc_data"),
                                                           ResourceManager.getResourceManager().loadFile("enc_data"),
                                                           1361531132);
        parser.start();
    } catch (Exception e) {
        mRequestStates.put("enc", false);
        EventBus.getDefault().post(EVENT_ENCYCLOPEDIA_DOWNLOAD_COMPLETE);
    }
}

这是解析器线程。有两个构造函数 - 一个用于从web加载(字符串参数),另一个用于从文件加载(InputStream param)。

    private static class EncyclopediaParser extends Thread {
    // -----------------------------------------------------------------------
    //
    // Fields
    //
    // -----------------------------------------------------------------------
    private String mJsonData;
    private Reader mTitlesReader;
    private Reader mContentReader;
    private long mUpdateTime;

    // -----------------------------------------------------------------------
    //
    // Constructor
    //
    // -----------------------------------------------------------------------
    public EncyclopediaParser(String jsonData, long updateTime) {
        mJsonData = jsonData;
        mUpdateTime = updateTime;
        this.setPriority(Thread.NORM_PRIORITY - 1);
    }

    public EncyclopediaParser(Reader titlesReader, Reader contentReader, long updateTime) {
        mTitlesReader = titlesReader;
        mContentReader = contentReader;
        mUpdateTime = updateTime;
        this.setPriority(Thread.NORM_PRIORITY - 1);
    }

    // -----------------------------------------------------------------------
    //
    // Methods
    //
    // -----------------------------------------------------------------------
    @Override
    public void run() {
        Type type;

        try {
            List<ArticleContent> content = null;
            type = new TypeToken<Collection<ArticleContent>>(){}.getType();
            if(mContentReader == null)
                content = new Gson().fromJson(mJsonData, type);
            else
                content = new Gson().fromJson(mContentReader, type);

            List<ArticleTitle> titles = null;
            type = new TypeToken<Collection<ArticleTitle>>(){}.getType();
            if(mTitlesReader == null)
                titles = new Gson().fromJson(mJsonData, type);
            else
                titles = new Gson().fromJson(mTitlesReader, type);

            for(ArticleTitle title : titles)
                title.setTitle(title.getTitle().trim());

            TitlesComparator titlesComparator = new TitlesComparator();
            Collections.sort(titles, titlesComparator);
            for(int i = 0; i < titles.size(); ++i)   //sorting enc data
                titles.get(i).setOrderValue((long)i);

            //create sections data
            Collator collator = Collator.getInstance(Locale.GERMAN);
            collator.setStrength(Collator.PRIMARY);
            ArrayList<String> sectionNamesList = new ArrayList<String>();
            ArrayList<Integer> sectionIndexesList = new ArrayList<Integer>();
            String prevLetter = "";
            for (int i = 0; i < titles.size(); ++i) {
                if(titles.get(i).getTitle().length() > 0){
                    if(!Character.isLetter(titles.get(i).getTitle().charAt(0))) {
                        if( !sectionNamesList.contains("#")) {
                            sectionNamesList.add("#");
                            sectionIndexesList.add(i);
                        }
                    }
                    else if(collator.compare(titles.get(i).getTitle().substring(0, 1), prevLetter) > 0) {
                        sectionNamesList.add(titles.get(i).getTitle().substring(0, 1).toUpperCase(Locale.GERMAN));
                        sectionIndexesList.add(i);
                    }
                    prevLetter = titles.get(i).getTitle().substring(0, 1);
                }
            }
            String[] sectionNames = new String[sectionNamesList.size()]; //use lists instead
            Integer[] sectionIndexes = new Integer[sectionIndexesList.size()];
            sectionNamesList.toArray(sectionNames);
            sectionIndexesList.toArray(sectionIndexes);
            AppData.setSectionIndexes(Utils.convertIntegers(sectionIndexes));
            AppData.setSectionNames(sectionNames);

            GreenDAO.getGreenDAO().insertArticles(titles, content);
            AppData.setEncyclopediaUpdateTime(mUpdateTime);
            mRequestStates.put("enc", false);
            if(mTitlesReader != null)
                mTitlesReader.close();
            if(mContentReader != null)
                mContentReader.close();
        } catch (Exception e) {
            Log.e("Server", e.toString());
        } finally {
            EventBus.getDefault().post(EVENT_ENCYCLOPEDIA_DOWNLOAD_COMPLETE);
        }
    }
}

所有GreenDAO对象都是静态的。解析仅在第一次启动(从文件)和“更新”按钮单击(从Web)完成。我注意到,即使我在初始(从文件)解析完成后重新启动我的应用程序,它将使用尽可能多的内存,因为它是第一次完成解析后。

0 个答案:

没有答案