2016-12-31 76 views
1

我在這個主題上看到了一些貼子,但沒有一個有滿意的答案。Android工作線程持續多久?

假設我從我的主(一次性)Activity,在其onCreate()方法中啓動一個工作線程。然後我打電話finish()導致Activity終止。

此時,它所屬的任務被破壞(因爲其中不再有任何Activity)。應用程序(以及運行它的進程)可能會繼續存在,但是,以空的「骨架」形式存在,以便在需要時可以快速重新啓動它(儘管它很容易被系統殺死)。

假設上述內容是正確的 - 何時工作者線程被殺害?只有在系統積極破壞過程時纔會被殺死?

在我的情況下,我的工作線程作爲藍牙連接的偵聽器存在;當收到時,它會再次啓動所需的Activity。在這種情況下,沒有主動運行的組件(ActivityServiceContentProviderBroadcastReceiver)。在我看來,這應該工作,除了有什麼是殺死我的工作線程。

我知道我可以通過使用背景Service來做到這一點(並減少疼痛)。但是,我很好奇爲什麼這不起作用。

感謝, 巴里

+0

我相信線程只會在Linux進程被破壞時自動終止。 – Enzokie

+0

_「在我看來,這應該工作,但有些事情是殺了我的工作線程」 _這隻能意味着[系統終止應用程序(http://stackoverflow.com/questions/34463069/can-android -kill-MY-APP-而-IT-是,在最中間的一環實施)。 _「只有在系統主動破壞進程時纔會被終止?」_正確(或者如果'run()'方法返回)。 – Onik

+0

同意。問題就變成了,這個過程何時被殺死?我的猜測是,當沒有更多的運行組件時它會被殺死,但我沒有看到明確記錄在任何地方。下面是我對Oleg的BroadcastReceiver響應的迴應。 –

回答

0

Android App lifecycle有一個很好的例子,這是非常對的話題:

過程生命週期的錯誤的一個常見的例子是一個BroadcastReceiver ,當它接收其 BroadcastReceiver.onReceive一個Intent來啓動一個線程()方法,然後從 函數返回。一旦它返回,系統認爲BroadcastReceiver 不再處於活動狀態,因此,其主機進程不再需要 (除非其他應用程序組件處於活動狀態)。因此,系統 可能會隨時終止進程以回收內存,並且這樣做會終止在進程中運行的衍生線程。

總之,如果你的線程會得到一個機會運行,直到終止或進程被事先殺死,那麼它確實不是非常可預測的,你不應該絕對依賴任何命令/行爲。

值得一提的分別是它的相當容易leak你用螺紋一起活動,即使你完成(),但如果你的最後/只有當你啓動一個線程它不會改變圖片

+0

如果活動有引用它,他只泄漏活動。如果他的主題不引用活動以任何方式,是一個靜態內部類還是非內部類,沒有活動的泄漏,但只有Thread類持有引用。 –

+0

他並不需要有明確的參考,它足以說新的Thread(){...}中的onCreate獲得隱式引用和繁榮 –

+0

不,它不是。只有當Thread是一個非靜態的內部類時,情況纔是真的。你的例子是什麼(它是一個非靜態的匿名內部類),但不一定是這種情況。靜態內部類沒有對父類的引用。 –

-1

有一個主(也稱爲UI)線程的Android。這是你的應用程序使用的唯一線程,除非它通過Thread.start()AsyncTask.execute()等明確啓動。所有活動,服務,BroadcastReceivers等都在該主線程上運行其所有生命週期方法。注意我包含了服務 - 一個服務在主線程上運行,除非它啓動它自己的線程(例外是IntentService,它運行在它自己的線程上)。

A Thread您創建繼續,直到它的Runnable從其運行函數返回(或當然過程終止)。這可以活過它創建的Activity/Service的末尾。然而,這樣一個線程仍然會存在於組件的原始實例中,並且如果沒有很多特殊工作(請參閱加載程序模式)重新啓動它,將無法訪問新實例的變量。

+0

作者提到什麼與您的陳述相矛盾?他只是從onCreate衍生出一個線程 –

+0

更正主線程有時是**被稱爲UI線程。 – Enzokie

+0

@OlegBogdanov我最初誤解他的問題,因爲認爲onCreate啓動了一個線程。我刪除了你是錯誤的部分。 –

0

活動,它獨立於開始它的父母。就你而言,這是你的應用程序活動。這意味着在Run方法完全執行之前,你的線程將會存活。

如果退出應用程序(並因此調用活動的方法的onStop),線程仍然存在,並且您將導致內存泄漏。如果內存不足,它最終會被系統殺死。

既然你提到你創建了一個偵聽器來偵聽藍牙連接,它接收到的任何事件(這是不可能的,我知道沒有任何的代碼片段)之前,你的線程可能死亡。它也可能會崩潰,這將結束線程。

+0

內存泄漏只發生在線程持有活動引用時。 – Enzokie

+0

線程可以保存除活動之外的其他內容的引用,這會引起所述引用的泄漏 –

+0

說明:我*希望*工作線程繼續存在,並且我注意不要在其執行後生成任何新線程。從概念上講,至少,這將允許它接受傳入的藍牙請求,並在發生這種情況時觸發相關的活動。所以不會有內存泄漏(只要我仔細地編寫工作線程) - 我只是爲了工作線程的目的而保留的內存。 –

1

當工作線程被殺?只有在系統積極破壞過程時纔會被殺死?

- >工作線程熟練後,其所有的代碼run函數執行完畢。即使你的activity被破壞,它仍然會運行。

在我的情況下,我的工作線程作爲藍牙連接的偵聽器存在;當收到時,它會再次啓動所需的活動。在這種情況下,沒有主動運行的組件(Activity,Service,ContentProvider或BroadcastReceiver)。在我看來,這應該工作,除了有什麼是殺死我的工作線程。

爲了使它工作,你需要有在這種情況下,背景service並從您的工作線程或更簡單的做一個soft/weak參考您的service,使用EventBus從您Service作爲開始任何組件:

EventBus.getDefault().post(new BlueToothEvent()); // call in your worker thread 
// do something in your service 
onBlueToothEventFired(BlueToothEvent e);