【问题标题】:How to make (and save in RAM) sparsearray at app launch? (android)如何在应用程序启动时制作(并保存在 RAM 中)稀疏数组? (安卓)
【发布时间】:2013-03-20 06:49:06
【问题描述】:

我正在制作一个安卓应用程序。应用程序中有一个活动,当它被触发时,它会生成一个稀疏数组并用数据填充它。现在这个过程在模拟器上最多需要 1 分钟,这很长。所以我想在应用程序启动时创建一次稀疏数组,并将稀疏数组保存在 RAM 中以供应用程序的生命周期使用。并且无论何时触发活动,它都应该访问 RAM 中的稀疏数组,而不是创建一个新数组,从而节省时间和处理能力。这可以做到吗,如果可以,怎么做?对不起,如果这个问题很愚蠢,我是安卓新手。谢谢! *编辑:这是稀疏数组制作函数的样子: //访问sparsearray制作函数的函数

public String[] process(){
InputStream is = context.getAssets().open("feedtitlesandaddresses.txt");
        InputStreamReader iz=new InputStreamReader(is);
        BufferedReader br = new BufferedReader(iz);
        String line = null;
while((line=br.readLine())!=null) {

            readLine(line);

            }}
//sparsearray making function
private void readLine(String line) {
//some string processing(omitted here)
int num1 = Integer.parseInt(firstNumber);

        //int num2 = Integer.parseInt(secondNumber);
        if(sparseArray.get(num1) == null) {

            sparseArray.put(num1, new SparseArray<String>());

        }
        temporarySparseArray = sparseArray.get(num1);

        for(int w=0;w<size;w++){
        temporarySparseArray.put(w, array1[w]);
                }
        sparseArray.put(num1, temporarySparseArray);

        temporarySparseArray = null;
}

【问题讨论】:

  • 你能提供一些代码吗?如果你的 AVD 只有几兆赫兹,它会很慢。
  • @staaar 我怎样才能知道我的 AVD 有多少 MHz?
  • @staaar 代码的哪一部分?
  • @TomWong 在您的onCreate() 对象的onCreate() 中启动一个线程或AsyncTask 并将结果保存在那里。
  • @staaar 我已经添加了代码

标签: java android sparse-array


【解决方案1】:

您可以在android内部或外部文件系统中写入您的对象,您可以在需要使用时读取该对象。

【讨论】:

  • 您建议从文件系统读取和写入对象的哪些方式,以及它们的性能如何取决于对象的大小?如果原始数据发生变化,会有什么影响?
【解决方案2】:

我觉得这个问题值得回答,而且我确信有人会想出一个答案,但是,嗯,到目前为止还没有;如果我是 Tom Wong,目前在我看来,StackOverflow 似乎是一个想要成为专家的地方,他们开始争执而不是回答问题。 ;) 所以我们开始吧。

  • 在启动时做一些事情,只要你的应用程序在内存中,其结果就会持续:这样做的正确位置是Application.onCreate(),你需要子类化Application。在这种情况下,也可以将结果存储在Application 对象中,您可以通过获取应用程序上下文从任何Activity 访问它。

  • 做一些需要一些时间的事情:一般来说,在 Android 上使用AsyncTask 是个好主意,但它专门用于做与用户界面相关但不能阻止它的事情。此外,如果没有一些明确的调整,它的行为会因不同的 Android 版本而异。目前,如果没有进一步的措施,如果您通过 AsyncTask 进行计算,其他 AsyncTask 将不得不先等待。此外,您想要做的不是使用 AsyncTask 的经典任务,因此请使用一次性线程,它最终将其结果简单地存储在 volatile 引用中。

下面的代码 sn-p 应该会给你这个想法。

final class MyApplication extends Application {
    public volatile String[] expensiveToCompute;
    @Override
    public void onCreate() {
        expensiveToCreate = null;
        (new Thread() {
            @Override
            public void run() {
                String[] result = computeMyData();
                // it is important to assign the locally created data at once here
                expensiveToCompute = result;
            }
        }).start();
    }
}

这样,expensiveToCompute 将是null,直到异步计算完成。

重要的是要了解此线程将一直运行到它完成,并且它持有对您的MyApplication 对象的引用。这意味着即使用户离开了您的应用,您的 Thread 仍将继续,如果它直到那时还没有完成。

这实际上很好,因为 Android 决定让您的 Application 对象保持活动状态只是因为它可以,在这种情况下用户体验会得到改善。或者 Android 会使用 Application 对象、您的 Thread 和任何持有的数据终止整个进程,在这种情况下,它将在下次从头开始。

还有一件事,嗯,建议将昂贵的计算转移到 AsyncTask 等:Android 为此类线程分配默认的后台优先级,并且所有后台线程(当前)必须总共使用 10% 的 CPU 时间不管Android系统是否空闲。许多将密集计算转移到后台任务的人注意到,这将花费十倍的时间。因此,您可能想阅读我关于如何处理 here 和/或 here 的建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 2014-05-25
    相关资源
    最近更新 更多