【问题标题】:Initializing an Android application初始化 Android 应用程序
【发布时间】:2010-09-10 17:25:50
【问题描述】:

我目前面临以下问题:每当我的 Android 应用程序启动时,它都需要执行一些耗时的初始化代码。如果没有此代码,我在应用程序中的所有活动/服务都将无法正常工作。

到目前为止,我已将此初始化代码放入 SplashScreen 活动中,我在清单中将其声明为 MAIN 活动。执行完初始化代码后,我完成()初始屏幕并启动实际的主要活动,即一个由多个选项卡组成的活动,用户可以从中访问其他几个活动。

现在的问题如下:当我的应用程序被置于后台时,经过一段时间并在启动其他应用程序后,我的应用程序/进程被终止。当我从主屏幕重新启动它时,Android 会恢复活动堆栈(任务)并在它们上调用 onCreate()。但是,启动屏幕活动和初始化代码没有被执行,这会导致异常。

我现在可以将初始化代码放在应用程序的 onCreate() 中,但这会导致黑屏,直到方法完成。

有人知道我可以在哪里以及如何在启动时正确初始化我的应用程序吗?

初始化代码:

public void init() {
    if (initialized) {
        return;
    }

    // Initialize terms
    List<Tag> tags= DynamicDao.loadAll(Tag.class);
    int numTags = tags.size();
    terms = new String[numTags];
    for (int i = 0; i < numTags; i++) {
        terms[i] = tags.get(i).getTag();
    }

    // Initialize document-term matrix
    List<Item> items = DynamicDao.loadAll(Item.class);
    createDocumentTermMatrix(items);

    initialized = true;
}

注意:一个项目有几个相关的标签,我需要从中创建一个文档向量。

【问题讨论】:

    标签: java android sdk android-activity


    【解决方案1】:

    你的初始化有多昂贵?你在那儿做什么?一般来说,我建议不要使用闪屏(它是移动应用程序,而不是桌面应用程序)。相反,在显示主 UI 时使用工作线程初始化数据,然后在工作线程完成后使用处理程序初始化 UI。

    或者,我会调查为什么您的初始化需要这么长时间,并对其进行优化。你在那里做什么?

    【讨论】:

    • 在初始化期间,我创建了一个大小为 50x70 的双精度矩阵,以便之后加快某些计算。这个计算在 Nexus One 上大约需要 2-3 秒,在 HTC Magic 上大约需要 6 秒,在模拟器上还需要更长的时间。初始化算法不能再优化了。最终(但我不太相信这个想法)我可以在第一次启动应用程序时将这个计算的结果写入一个文件,然后读取并从那里更新......
    • 写 3500 个双打不应该花费 3 秒。好像出了点问题
    • 也许我需要提供更多细节:这个矩阵是一个 word-document 矩阵,我使用应用程序的 SQLite DB 中的条目预先计算它,然后用它来计算相似度。跨度>
    • 您添加了计时器吗?查看此代码块的每个部分需要多长时间。测量执行 loadAll 所需的时间、for 循环的时间和 createDocumentTermMatrix 的时间。
    • 更好的建议?你说的是叛国罪:)
    【解决方案2】:

    如果你真的需要执行一个持久的操作,那么你应该使用AsyncTask。它使用起来非常简单,它为您提供了两个函数,分别称为onPreExecuteonPostExecute,分别在操作之前和之后在主线程中调用。 所有昂贵的东西都应该放在 doInBackground 中,这将在工作线程中工作。

    当您执行该操作时,您可以显示一个进度对话框(在上面提到的 onPreExecute 中创建它),通过使用提供的回调之一显示您正在执行的操作的进度: onProgressUpdate 然后,您将关闭上述 onPostExecute

    中的对话框

    【讨论】:

    • 不知道为什么我不能评论其他答案将在这里评论:如果您要计算的矩阵被多个活动使用,而不是使该类成为单例,您可以轻松子类化应用程序(developer.android.com/reference/android/app/Application.html)类(只要您的应用程序的活动或服务之一正在运行,它就会存在),您可以在其中存储矩阵,然后可以从程序的任何部分访问该矩阵。
    • 从多个活动访问矩阵不是问题。问题是在哪里计算这个矩阵。在 SplashScreenActivity、单例线程类或 Application.onCreate() 中。 Application.onCreate() 不是一个选项,因为在计算正在进行之前用户会看到黑屏 - 我看不到任何自定义它的可能性,例如通过显示自定义图像。如果我使用 SplashScreenActivity,那么我会遇到问题中描述的问题。
    • 事实上我的观点(见主要答案)是使用 AsyncTask 来不阻塞主线程。在 任何 情况下都需要一个单独的线程,否则 UI 将被阻塞,而 AsyncTask 是一种在不同线程中执行某些操作并在操作结束时收到通知并更新进度的好方法和简单的方法也是(因此我提到了进度更新回调)。我提到 Application 类可以只是用于存储操作的结果,以便应用程序中存在的任何活动/服务都可以轻松访问。
    【解决方案3】:

    如果您想保留当前的初始屏幕,您有几个选择。

    如果您的数据结构不是太庞大,您可以将其存储在 onSaveInstanceState 并在 onRestoreInstanceState 和/或 onPostCreate 中恢复。

    如果数据太大,您可能只需要检查您的应用是否在 onResume 或其他各种启动方法(如 onRestart、onStart 等)中初始化。(我仍然有点模糊什么时候应该使用每个。)如果没有,请启动您的启动屏幕活动。

    其他人对此主题的建议也很好。但如果您需要快速修复,这可能对您有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      • 2016-04-26
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      相关资源
      最近更新 更多