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

Android应用程序和耗时的本机代码,android,multithreading,java-native-interface,Android,Multithreading,Java Native Interface,我正在开发一个图像处理Android应用程序。假设你有一个C++单元素对象,它提供了一些耗时的函数并分配了自己的内存。FrHeTeReFor,C++库将提供一些其他功能,也会花费一些时间。此函数将由singleton对象调用。它们可以分配自己的临时内存(在函数终止时释放),并需要与singleton对象交换数据。工作流程如下所示: 加载本地C++库,创建单对象(它将分配内存并从资产目录加载数据)。 用户使用应用程序界面选择图像并加载它 图像被传递到singleton对象,该对象将计算一些信息 用

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

  • 加载本地C++库,创建单对象(它将分配内存并从资产目录加载数据)。
  • 用户使用应用程序界面选择图像并加载它
  • 图像被传递到singleton对象,该对象将计算一些信息
  • 用户可以请求特定的图像处理算法,单件对象被要求调用相应的函数
  • 如果用户加载另一个映像,则从4重复或转到2(singleton对象将被重置(在步骤1上分配的内存将被保留,直到应用程序被删除)

  • 步骤2和步骤3是应用程序中最耗时的部分。我希望用户能够停止当前的处理,如果过多的时间,应用程序在耗时的处理算法期间保持响应。执行此应用程序最简单的方法是调用本机函数并等待,但这可能会阻塞UI。另一种方法是设计这些函数,每N个处理像素检查一个标志,以知道函数是否必须停止(这将允许我在发生时释放内存)。第三种选择可能是使用java线程,但如何使用?

    您必须在UI线程之外运行耗时的任务。您可以使用本机线程来实现这一点,但是在java中从后台线程调用本机函数会更简单—有几种方法可以做到这一点,例如异步任务,等等,您可以阅读相关内容

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

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


    如果您的处理过程将特别漫长,可以说,您不仅应该在后台进行处理,而且应该在Android服务的上下文中进行处理,而不是在活动的上下文中进行处理。第一种近似情况是,本机代码不关心差异,但是如果活动在处理过程中转到后台,则可能会发生什么情况-如果工作是在服务中完成的(或者更具体地说,如果流程包含活动的服务),如果可能的话,Android会让它继续运行。相比之下,如果进程只有一个活动,而该活动现在由于前景中存在其他东西而不处于活动状态,那么Android更有可能杀死它或限制它的可用CPU。最终,无论您做什么,您的本机代码都需要处理其进程在工作完成之前被终止的可能性——即,当用户将活动返回前台时,您必须能够从创建新进程时的这种状态中恢复。让您的标志也能够将onDestroy()调用的本机代码作为警报通知以保存其工作可能会有所帮助,但它仍然需要能够在没有该通知的情况下从被终止的代码中恢复(至少干净地重新执行)。

    所有进程智能TAK都需要在单独的线程上执行。您有三个选项:异步任务、线程、加载程序。我有一个问题。你说,当用户将你的活动返回前台时,应用程序应该能够“从创建新进程时的这种状态中恢复”。这让我感到困惑,因为我认为应用程序进程只有在调用onDestroy()之后才会结束。这段话也让我感到困惑:“但它仍然需要能够在没有通知的情况下从被杀中恢复(至少是干净地恢复)。”。每次应用程序被终止时都会调用onDestroy()方法,对吗?从文档中,我看到onPause()可能是活动的最后一个被调用的方法。不,Android也可以在没有任何警告的情况下终止进程。这并不是非常常见,因此必须重新计算结果是可以的,但它确实发生了,所以您需要确保它不会使您处于损坏状态,而自动、用户不可见的恢复是不可能的。此外,您可能不希望onPause()停止处理。