Android应用程序和耗时的本机代码

时间:2012-12-08 14:35:48

标签: android multithreading java-native-interface

我正在处理Android应用程序的图像处理。假设您有一个C ++单例对象,它提供了一些耗时的函数并分配了自己的内存。此外,C ++库还将提供一些其他功能,这些功能也将耗费一些时间。单个对象将调用此函数。他们可以分配自己的临时内存(将在函数终止时释放)并需要与singleton对象交换数据。工作流程如下:

  1. 加载了本机C ++库,创建了单例对象(它将从资产目录中分配内存和加载数据)。
  2. 用户使用应用程序界面选择图像并加载
  3. 将图像传递给将计算某些信息的单例对象
  4. 用户可以请求特定的图像处理算法,要求单例对象调用相应的函数
  5. 从4开始重复或者如果用户加载另一个图像则转到2(单个对象将被重置(步骤1中分配的内存将被保留,直到应用程序被终止)。
  6. 第2步和第3步是应用中最耗时的部分。如果通过太多时间并且应用程序在耗时的处理算法期间保持响应,我希望用户能够停止当前处理。执行此应用程序的最简单方法是调用本机函数并等待,但这可能会阻止UI。另一种方法是设计这些函数来检查每N个已处理像素的标志,以了解该函数是否必须停止(这将允许我在发生时释放内存)。第三种选择可能是使用java线程,但是如何?

1 个答案:

答案 0 :(得分:2)

您必须从UI线程运行耗时的任务。您可以使用本机线程执行此操作,但从java中的后台线程调用本机函数会更简单 - 您可以通过多种方式执行此操作,例如您可以阅读的异步任务等。

当您开始耗时的操作时,您将希望UI向用户显示某种忙碌指示符。 UI线程必须保持响应(即,用户可以“返回”或“回家”),但如果您愿意,可以禁用大多数其他控件。

您在后台线程中的本机操作将按照您的建议定期检查停止请求标志。您可能会发现最简单的方法是将其设置为本机标志,并使用从UI线程调用的另一个(简短)本机函数进行设置;可以选择让它成为一个java标志并从C调用java来检查它,但这看起来更复杂。

如果您的处理过程特别冗长,可以说您不仅应该在后台工作,而且应该在Android服务的上下文中而不是在活动的上下文中工作。首先,本机代码不会关心差异,但是如果在处理过程中活动进入后台会发生什么,可能会产生影响 - 如果工作是在服务中完成的(或者更具体地说,如果进程包含一个活跃的服务),Android会尽可能让它继续运行。相反,如果进程只有一个活动现在不活动,因为其他东西在前台,Android更有可能杀死它或限制其可用的CPU。最终,无论你做什么,你的本机代码都需要处理它的进程在工作完成之前被杀死的可能性 - 也就是说,当用户返回你的新进程时,你必须能够从这种状态中恢复活动到前台。让你的标志也能够通知onDestroy()调用的本机代码作为保存其工作的警报可能是一个帮助,但它仍然需要能够恢复(至少干净地重做)没有被杀死没有礼貌的礼貌。