Java 在onDestroy中执行长时间运行操作

Java 在onDestroy中执行长时间运行操作,java,android,multithreading,lifecycle,jmdns,Java,Android,Multithreading,Lifecycle,Jmdns,我需要在我的活动的ondestory()中执行一个“长时间运行”清理操作。最好的方法是什么 如果我使用线程执行此操作,我的onDestroy()将立即返回;但是线程引用会发生什么呢?我在这里寻找关于我需要注意的任何暗示/陷阱/绊倒线的建议,因为我假设即使在活动被破坏之后,该过程仍将是活动的 背景: 我正在我的应用程序中使用。当用户使用完我的应用程序后,我想清理JmDNS实例。我使用JmDNS类的close()方法来实现这一点。但是,此方法需要超过5秒才能完成。因此,用户在触摸后退键后很长一段时

我需要在我的
活动的
ondestory()
中执行一个“长时间运行”清理操作。最好的方法是什么

如果我使用
线程执行此操作,我的
onDestroy()
将立即返回;但是线程引用会发生什么呢?我在这里寻找关于我需要注意的任何暗示/陷阱/绊倒线的建议,因为我假设即使在活动被破坏之后,该过程仍将是活动的


背景: 我正在我的应用程序中使用。当用户使用完我的应用程序后,我想清理JmDNS实例。我使用
JmDNS
类的
close()
方法来实现这一点。但是,此方法需要超过5秒才能完成。因此,用户在触摸后退键后很长一段时间都会在屏幕上看到我的
活动


我还没有弄清楚为什么
close()
要花那么长时间,但同时我也意识到我真的不需要等待关闭成功完成。我所需要的只是一种“触发”关闭并完成它的方法。

尝试在
onBackPressed()
中启动线程,并在线程完成时调用
destroy()

我完成了我在问题中提出的操作-我启动
线程来执行
onDestroy()中的长时间运行操作

我必须考虑的是,即使在长时间运行完成之前,用户重新打开了应用程序。在我的应用程序中,这意味着将创建一个新的JmDNS实例。因此,我在我的

ondestory
中分别清理每个实例

您的用例可能会有所不同-您可能希望仅在清理线程尚未运行时启动清理线程(使用
线程
isAlive()
方法或类似技术)

下面是一些示例代码。要了解“分别清理每个实例”部分,请执行以下步骤序列:

  • 启动应用程序
  • 按后退按钮。您将在LogCat中看到清理操作
  • 重新启动应用程序
  • 再次退出应用程序。现在,您将看到两组清理日志-第一组表示第一个实例的清理;以及对应于第二实例的第二集合

    public class DelayedExitActivity extends Activity {
    
        private static final String LOG_TAG = "DelayedExit";
        private final  Runnable longOperation = new Runnable(){
            @Override
            public void run() {
                for (int i=0 ; i < 50; i++){
                    Log.d(LOG_TAG, "Iteration "+i);
                    try {
                        Thread.sleep(2 * 1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };
        private Thread longThread ;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    
        @Override
        protected void onDestroy() {
            if(longThread == null){
                longThread = new Thread(longOperation);
            }
            longThread.start();
            super.onDestroy();
        }
    }
    
    公共类DelayedExit活动扩展活动{
    私有静态最终字符串LOG_TAG=“DelayedExit”;
    private final Runnable longOperation=new Runnable(){
    @凌驾
    公开募捐{
    对于(int i=0;i<50;i++){
    Log.d(Log_标签,“迭代”+i);
    试一试{
    线程。睡眠(2*1000);
    }捕捉(中断异常e){
    //TODO自动生成的捕捉块
    e、 printStackTrace();
    }
    }
    }
    };
    私有线程长线程;
    /**在首次创建活动时调用*/
    @凌驾
    创建时的公共void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    }
    @凌驾
    受保护的空onDestroy(){
    if(longThread==null){
    长线程=新线程(长操作);
    }
    longThread.start();
    super.ondestory();
    }
    }
    

  • Jmdns通常用于发现网络服务,我不知道为什么需要保持它打开并运行,直到应用程序最终关闭。我通常在找到远程服务器并完成操作后立即关闭它,同时向用户提示ProgressDialog。是的,这是我的正常使用情况。我还有另一个用例,我需要在应用程序的整个生命周期中持续监视被发现/删除的服务,并采取相应的行动。你的意思是,一旦线程完成,我就应该调用
    finish()
    ?在这种情况下,用户在按Back键时希望看到什么?是的,我的意思是您应该调用finish()。Yuo可以在按后退键时显示ProgressDialog或其他任何内容。我不愿意让用户等待我的应用程序关闭!由于我对清理操作的结果不感兴趣,我想知道是否可以在线程中启动清理,然后继续执行
    活动
    销毁。这样,当清理在后台进行时,用户立即“退出”应用程序。我唯一关心的是背景线程会发生什么;如果用户在后台线程完成之前重新启动我的应用程序,会发生什么情况?如果你的应用程序不使用线程使用的相同东西,而不处理切换到另一个活动并在稍后从停止状态销毁,则不会发生什么事。请向阅读此解决方案的人致意。它可以工作,但请注意,这将保留对活动的隐式引用,并且只要此操作处于活动状态,您就会有内存泄漏。