2014-04-01 61 views
6

我只是接近Android服務,但我有很多疑惑。這裏有一些問題。 在開始之前,請注意我已閱讀這些頁面 Android Services (official) Bounded Services (official) plus sone內在類語言在我的語言。請耐心等待,我仍然有點困惑。所有的請介紹一些Android的服務理念

1)首先,服務區別於一個的AsyncTask主要是因爲它繼續運行也如果應用被暫停(即,用戶正在觀看其他應用); AsyncTask在這種情況下被停止。是好的還是我錯了? 2)服務在通過startService()啓動它的活動的同一線程中運行。 爲了不影響活動的性能,我必須爲該服務創建一個單獨的線程,例如實現Runnable接口。另一種方法是創建一個擴展IntentService的服務,該服務自動爲該服務提供一個新線程:在任何onHandleIntent()調用上創建一個新線程。

現在,讓我們看一下我的具體問題。我需要創建一個將被許多活動使用的服務:他的任務是每60秒連接一次服務器數據庫並檢查新聞。如果發現新聞,通知有新消息(如果我們在MainActivity上)或顯示新消息的標題(如果我們在新聞閱讀器中)。我應該如何編碼? 我做了一個實例化NewsService並立即調用startService()的MainActivity。另一方面,我有NewsService擴展IntentService,(當onHandleIntent被調用時創建一個新線程?)並尋找新消息。使用IntentService是不是一個好主意?我意識到,無限期地啓動服務調用startService()會非常難看。 在這個練習的開始,我付出了努力,這是一個很好的解決方案,因爲它會自動創建一個新的線程並使服務實現變得簡單。但現在我有一些疑惑(我不知道是否有新聞!MainActivity如何知道它?以及如何獲得標題)

這應該用一個正常擴展的Thread類來完成,它使得無限的cicle在run()方法中,每60秒檢查一次新聞,如果有新的,從遠程DB讀取標題並更新活動按鈕/視圖。然後,如果應用程序將被用戶關閉,服務也將被關閉。 但問題是,如果我istantiate這種類是當在MainActivity暫停或停止工作將停止,因爲新的線程不會在此刻獲得新聞等活動(在這種情況下播音員)不能得到任何更新。所以我需要一個服務。

我希望這是清楚的。我應該如何以正確的方式實施解決方案? 請突顯一切錯在我的文字,我真的需要學習:d

回答

1

你似乎已經正確地明白了一切。

至於你的具體問題,我建議如下:

  • 使用AlarmManager安排您服務。不要讓Service在不需要時運行。

  • 使用Broadcast Intent獲取新消息。所有Activities將必須有一個內部BroadcastReceiver,它傾聽服務的意圖,並作出相應的反應。

+0

謝謝。我其實對廣播意圖和廣播接收器一無所知:如果沒有人給我一個解決方案,我會直接閱讀相關的文檔:D。順便說一句,我不能相信我已經瞭解了一切xD – mark

+1

這可能會給你一些'廣播'的理解:http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html –

+0

此外,這篇文章有關於安排通過'AlarmManager'服務並通過'Broadcasts'發佈更新:http://www.vogella.com/tutorials/AndroidServices/article.html –

0

服務是你想要的東西,他們都相當好做消耗很少的資源,如保持在後臺守護進程的好辦法,他們也很好地顯示沒有活動通知,並保持運行,即使你退出活動。

當您需要在服務中執行更多繁重的操作時,您仍然可以使用AsyncTask,啓動它,在另一個線程中執行您的操作並自動在您的主線程中接收結果。

如果你想保持服務始終運行,你可以在你的服務

@Override 
    public int onStartCommand(final Intent intent, final int flags, 
     final int startId) { 
    // Ensure the service will restart if it dies 
    return START_STICKY; 
    } 

使用START_STICKY你可以啓動該服務做:

final Intent service = new Intent(); 
service.setComponent(new ComponentName(YourService.PACKAGE_NAME, 
    YourService.SERVICE_FULL_NAME)); 

// Start the service 
context.startService(service); 
0

1)首先,服務與AsyncTask 的差異主要在於,如果應用程序暫停(即 用戶正在觀看其他應用程序),它也會繼續運行; AsyncTask在這種情況下被停止。是 它確定或我錯了嗎?

這是不正確的。 AsyncTask是一種用於將後臺處理卸載到單獨線程並提供通知用戶進程,錯誤和完成後臺處理的機制。如果應用程序暫停,AsyncTask不會停止工作。它繼續在後臺執行處理。一般而言,AsyncTask和啓動它的Activity之間存在緊密耦合。

另一方面,Service(通常)與啓動它的Activity完全分離。 A Service有自己的生命週期,獨立於應用中的其他活動。此外,服務沒有UI,因此它們不與應用程序的可視化元素相關聯,並且它們不提供與進度,錯誤或完成相關的視覺反饋的(直接)機制。這需要單獨編程。

2)服務運行在 活動的同一線程中,該活動通過startService()啓動它。爲了不影響 活動的表現,我必須爲該 服務創建一個單獨的線程,例如實現Runnable接口。另一個 方法正在製作擴展IntentService的服務,其中 會自動爲該服務提供一個新線程:在任何onHandleIntent()調用上創建的新線程爲 。

這也是不正確的。 A Service不在任何特定線程上運行。主線程(UI)上運行的ServiceonCreate(),onStartCommand()等)的生命週期方法(可能是也可能不是調用startService()的相同線程)。但是,Service可以(並且通常會)啓動其他後臺線程(儘可能多)來執行必要的工作。

IntentService是一種特定類型的Service,它管理一個或多個用於執行後臺處理的工作線程。您向IntentService發送一個「命令」,然後IntentService將您的命令放入隊列中。在某些時候(不同Android版本中的不同實現行爲會有所不同),您的「命令」將在後臺線程中出列並處理。 IntentService在處理完所有「命令」後自行停止。由於其行爲方式,IntentService通常不是Service的最佳選擇。


IntentService絕對不是你想要的你的情況。您應該使用AlarmManager並設置每分鐘開始Service的警報。當你的Service啓動時,它應該創建一個後臺線程來聯繫你的服務器並檢查新聞。如果沒有消息,它可以消失。如果有新消息,它可以啓動您的Activity來通知用戶,或者它可以發送您的Activity將看到的廣播Intent(如果它正在運行),或者它可以創建Notification,然後用戶可以隨時打開它想要。您需要弄清楚您應該如何確定應用何時應該停止檢查服務器。也許用戶應該告訴你他不再感興趣,或者Service可以認識到該應用程序不再運行(或者在超過X小時或更長時間內未被查看)。有很多方法可以做到這一點,這取決於您的要求。