2011-06-01 88 views
15

在我的Android应用中,主Activity有时会启动一个Thread来从服务器加载数据。此线程修改应用程序的数据库并编辑一些重要的文件。 AFAIK,看来这个线程继续执行。如果Android进入低内存环境并决定终止整个应用程序,该线程会发生什么?这个线程是否会过早死亡?如果是这样,有什么办法可以看到线程正在被杀死,并对此做些什么?在创建它的Activity被销毁后,Android线程会发生什么?

我在问,因为这个线程修改数据库中的重要数据,如果它突然死亡,应用程序可能会停止正常运行。

回答

13

据我所知,它会出现,这个线程继续执行。

这是事实,但您无法保证线程将保持活动状态的时间。

如果Android进入低内存状态并决定终止整个应用程序,该线程会发生什么?

在我的经验中,这实际上是一个相当罕见的情况,但它取决于设备的可用内存和用户行为,例如他们大量使用设备并启动多个应用程序。

这个线程是否会过早死亡?

如果是这样,有什么办法可以看到线程被杀害,并做些什么呢?

没有

我这么问是因为这个线程修改数据库中的重要数据,如果它突然被杀,应用程序可能停止正常工作。

你所描述的可能被归类为'关键任务'。正如另外两个答案指出的那样,服务将是一种更强大的做事方式,因为服务是在内存不足情况下最后被“杀死”的事情之一。使用START_REDELIVER_INTENT可能有助于恢复正在执行的操作。在任何情况下,如果您有“任务关键”操作,则需要设计用于完全恢复的代码,例如使用事务以及在发生错误时进行回滚的可能性。

+0

当然,你可以对此做些事情。但是,一旦你允许应用程序被销毁 - 比'onDestroy'快 - 在'onStop'设置一个线程可以轮询的标志,以知道应用程序可能会消失。在'onResume'中清除该标志。线程尽可能以尽量短的块来完成它的工作,并且如果它看到该标记,它就会自行结束。在每个块结束时,它会更新文件进度的状态,因此可以正确重启。同样在'onStop'中,直到'!thread.isAlive'或者1秒才会返回 - 使用测试和计数器循环并且每次睡眠100毫秒,不超过10次。 – ToolmakerSteve 2016-09-22 12:52:36

+0

线程在长时间延迟后(例如服务器响应)以及执行关键操作(更新本地文件/数据库)之前还需要检查标志。它永远不会开始使用该标志集的关键部分。只要临界部分不超过100-200毫秒,我认为你在实践中是安全的。 (并不是说这是关键任务应用程序的好方法,但对我们大多数人来说已经足够了)。注意我的方法的本质是在你的应用程序还活着的时候开展工作* - 通过延迟onStop来达到1第二。对于很多情况,这是所需要的。 – ToolmakerSteve 2016-09-22 12:57:34

+0

更新:我的延迟到1秒的建议太长,以至于不适合'onStop'。需要研究合适的时间 - Android对合理时间的定义是什么。请注意,如果Android *应该有任何UI调用会有点宽松,那么它就是'onStop',因为这是应用程序的最后机会,以确保它们保留了他们所关心的任何内容。 – ToolmakerSteve 2016-09-22 13:04:58

5

这听起来像你应该将数据库更新移动到服务。一旦Activity进入后台,Android会认为它的进程可以在必要时关闭,稍后重新启动而不会产生任何不良影响。有关更多信息,请参阅Application Fundamentals

3

我可能会挖出一个旧线程,但没有人提到一个重要的事情。

每次使用数据库并修改多行时,都应该使用事务来确保数据在发生任何类型的故障时保持有效(这可能是例如线程终止,套接字异常等) 。

try{ 
     db.beginTransaction(); 

     //Do whatever you need to do...  

     db.setTransactionSuccessful(); 
    }catch(SQLiteException e){ 
     Log.e("SQLite","Error while updating rows: " + e.getMessage()); 
    }finally{ 
     db.endTransaction(); //Commit (if everything ok) or rollback (if any error occured). 
     db.close(); //Close databse; 
    } 
相关问题