• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Dịch vụ
2@jd:body
3
4<div id="qv-wrapper">
5<ol id="qv">
6<h2>Trong tài liệu này</h2>
7<ol>
8<li><a href="#Basics">Nội dung Cơ bản</a></li>
9<ol>
10  <li><a href="#Declaring">Khai báo một dịch vụ trong bản kê khai</a></li>
11</ol>
12<li><a href="#CreatingAService">Tạo một Dịch vụ được Bắt đầu</a>
13  <ol>
14    <li><a href="#ExtendingIntentService">Mở rộng lớp IntentService</a></li>
15    <li><a href="#ExtendingService">Mở rộng lớp Dịch vụ</a></li>
16    <li><a href="#StartingAService">Bắt đầu một dịch vụ</a></li>
17    <li><a href="#Stopping">Dừng một dịch vụ</a></li>
18  </ol>
19</li>
20<li><a href="#CreatingBoundService">Tạo một Dịch vụ Gắn kết</a></li>
21<li><a href="#Notifications">Gửi Thông báo tới Người dùng</a></li>
22<li><a href="#Foreground">Chạy một Dịch vụ trong Tiền cảnh</a></li>
23<li><a href="#Lifecycle">Quản lý Vòng đời của một Dịch vụ</a>
24<ol>
25  <li><a href="#LifecycleCallbacks">Triển khai gọi lại vòng đời</a></li>
26</ol>
27</li>
28</ol>
29
30<h2>Lớp khóa</h2>
31<ol>
32  <li>{@link android.app.Service}</li>
33  <li>{@link android.app.IntentService}</li>
34</ol>
35
36<h2>Mẫu</h2>
37<ol>
38  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code
39      ServiceStartArguments}</a></li>
40  <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
41      LocalService}</a></li>
42</ol>
43
44<h2>Xem thêm</h2>
45<ol>
46<li><a href="{@docRoot}guide/components/bound-services.html">Dịch vụ Gắn kết</a></li>
47</ol>
48
49</div>
50
51
52<p>{@link android.app.Service} là một thành phần ứng dụng có khả năng thực hiện
53các thao tác chạy kéo dài trong nền và không cung cấp giao diện người dùng. Một
54thành phần ứng dụng khác có thể bắt đầu một dịch vụ và nó sẽ tiếp tục chạy ngầm ngay cả khi người dùng
55chuyển sang một ứng dụng khác. Ngoài ra, một thành phần có thể gắn kết với một dịch vụ để
56tương tác với nó và thậm chí thực hiện truyền thông liên tiến trình (IPC). Ví dụ, một dịch vụ có thể
57xử lý các giao dịch mạng, phát nhạc, thực hiện I/O tệp, hoặc tương tác với một trình cung cấp nội dung, tất cả
58đều xuất phát từ nền.</p>
59
60<p>Về cơ bản, một dịch vụ có thể có hai dạng:</p>
61
62<dl>
63  <dt>Được bắt đầu</dt>
64  <dd>Dịch vụ có dạng "được bắt đầu" khi một thành phần ứng dụng (chẳng hạn như một hoạt động) bắt đầu nó bằng cách
65gọi {@link android.content.Context#startService startService()}. Sau khi được bắt đầu, dịch vụ
66có thể chạy ngầm vô thời hạn, ngay cả khi thành phần bắt đầu nó bị hủy. Thông thường,
67dịch vụ được bắt đầu sẽ thực hiện một thao tác đơn lẻ và không trả về kết quả cho hàm gọi.
68Ví dụ, nó có thể tải xuống hoặc tải lên một tệp thông qua mạng. Khi thao tác được hoàn thành, dịch vụ
69tự nó sẽ dừng lại.</dd>
70  <dt>Gắn kết</dt>
71  <dd>Dịch vụ có dạng "gắn kết" khi một thành phần ứng dụng gắn kết với nó bằng cách gọi {@link
72android.content.Context#bindService bindService()}. Dịch vụ gắn kết sẽ đưa ra
73một giao diện máy khách-máy chủ cho phép các thành phần tương tác với dịch vụ, gửi yêu cầu, nhận kết quả, và thậm chí
74làm vậy thông qua truyền thông liên tiến trình (IPC). Dịch vụ gắn kết chỉ chạy trong khi
75một thành phần ứng dụng khác được gắn kết với nó. Nhiều thành phần có thể gắn kết cùng lúc với dịch vụ,
76nhưng khi tất cả bị bỏ gắn kết thì dịch vụ sẽ bị hủy.</dd>
77</dl>
78
79<p>Mặc dù tài liệu này thường đề cập tới hai loại dịch vụ riêng rẽ, dịch vụ
80của bạn có thể hoạt động theo cả hai cách&mdash;nó có thể được bắt đầu (để chạy vô thời hạn) và cũng cho phép gắn kết.
81Đó đơn giản là vấn đề bạn có triển khai một cặp phương pháp gọi lại hay không: {@link
82android.app.Service#onStartCommand onStartCommand()} để cho phép thành phần bắt đầu nó và {@link
83android.app.Service#onBind onBind()} để cho phép nó gắn kết.</p>
84
85<p>Không phụ thuộc vào việc ứng dụng của bạn được bắt đầu, gắn kết, hay cả hai, bất kỳ thành phần ứng dụng nào
86cũng có thể sử dụng dịch vụ (thậm chí từ một ứng dụng riêng biệt), giống như cách mà bất kỳ thành phần nào cũng có thể sử dụng
87một hoạt động&mdash;bằng cách bắt đầu nó bằng một {@link android.content.Intent}. Tuy nhiên, bạn có thể khai báo
88dịch vụ là riêng tư trong tệp bản kê khai, và chặn truy cập từ các ứng dụng khác. Điều này
89được trình bày kỹ hơn trong phần về <a href="#Declaring">Khai báo dịch vụ trong
90bản kê khai</a>.</p>
91
92<p class="caution"><strong>Chú ý:</strong> Một dịch vụ chạy trong
93luồng chính của tiến trình lưu trữ của nó&mdash;dịch vụ <strong>không</strong> tạo luồng của chính nó
94và <strong>không</strong> chạy trong một tiến trình riêng biệt (trừ khi bạn quy định khác). Điều này có nghĩa
95là, nếu dịch vụ của bạn định thực hiện bất kỳ công việc nặng nào đối với CPU hay chặn các thao tác (chẳng hạn như phát lại MP3
96hay kết nối mạng), bạn nên tạo một luồng mới bên trong dịch vụ để thực hiện công việc đó. Bằng cách sử dụng
97một luồng riêng biệt, bạn sẽ giảm rủi ro gặp lỗi Ứng dụng Không Hồi đáp (ANR) và luồng chính của ứng dụng có thể
98vẫn dành riêng cho tương tác giữa người dùng với các hoạt động của bạn.</p>
99
100
101<h2 id="Basics">Nội dung Cơ bản</h2>
102
103<div class="sidebox-wrapper">
104<div class="sidebox">
105  <h3>Bạn nên sử dụng dịch vụ hay luồng?</h3>
106  <p>Dịch vụ đơn thuần là một thành phần có thể chạy ngầm ngay cả khi người dùng không
107đang tương tác với ứng dụng của bạn. Vì thế, bạn chỉ nên tạo một dịch vụ nếu đó là điều bạn
108cần.</p>
109  <p>Nếu bạn cần thực hiện công việc bên ngoài luồng chính của mình, nhưng chỉ trong khi người dùng đang tương tác với
110ứng dụng của bạn, thì thay vào đó, bạn nên tạo một luồng mới chứ không phải một dịch vụ. Ví
111dụ, nếu bạn muốn phát một bản nhạc, nhưng chỉ trong khi hoạt động của bạn đang chạy, bạn có thể tạo
112một luồng trong {@link android.app.Activity#onCreate onCreate()}, bắt đầu chạy nó trong {@link
113android.app.Activity#onStart onStart()}, rồi dừng nó trong {@link android.app.Activity#onStop
114onStop()}. Cũng xem xét việc sử dụng {@link android.os.AsyncTask} hoặc {@link android.os.HandlerThread},
115thay vì sử dụng lớp {@link java.lang.Thread} truyền thống. Xem tài liệu <a href="{@docRoot}guide/components/processes-and-threads.html#Threads">Tiến trình và
116Luồng</a> để biết thêm thông tin về luồng.</p>
117  <p>Hãy nhớ rằng nếu bạn sử dụng một dịch vụ, nó vẫn chạy trong luồng chính của ứng dụng của bạn theo
118mặc định, vì thế bạn vẫn nên tạo một luồng mới trong dịch vụ nếu nó thực hiện các thao tác tăng cường hoặc
119chặn.</p>
120</div>
121</div>
122
123<p>Để tạo một dịch vụ, bạn phải tạo một lớp con của {@link android.app.Service} (hoặc một
124trong các lớp con hiện tại của nó). Trong triển khai của mình, bạn cần khống chế một số phương pháp gọi lại có chức năng
125xử lý những khía cạnh chính trong vòng đời của dịch vụ và cung cấp một cơ chế để các thành phần gắn kết với
126dịch vụ đó, nếu phù hợp. Những phương pháp gọi lại quan trọng nhất mà bạn nên khống chế là:</p>
127
128<dl>
129  <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt>
130    <dd>Hệ thống sẽ gọi phương pháp này khi một thành phần khác, chẳng hạn như một hoạt động,
131yêu cầu dịch vụ phải được bắt đầu, bằng cách gọi {@link android.content.Context#startService
132startService()}. Sau khi phương pháp này thực thi, dịch vụ sẽ được bắt đầu và có thể chạy vô thời hạn trong
133nền. Nếu bạn triển khai điều này, bạn có trách nhiệm dừng dịch vụ khi
134công việc của nó được hoàn thành, bằng cách gọi {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
135android.content.Context#stopService stopService()}. (Nếu chỉ muốn cung cấp khả năng gắn kết, bạn không
136cần triển khai phương pháp này.)</dd>
137  <dt>{@link android.app.Service#onBind onBind()}</dt>
138    <dd>Hệ thống sẽ gọi phương pháp này khi một thành phần khác muốn gắn kết với
139dịch vụ (chẳng hạn như để thực hiện RPC), bằng cách gọi {@link android.content.Context#bindService
140bindService()}. Trong triển khai phương pháp này của mình, bạn phải cung cấp một giao diện mà các máy khách
141sử dụng để giao tiếp với dịch vụ, bằng cách trả về {@link android.os.IBinder}. Bạn phải luôn
142triển khai phương pháp này, nhưng nếu bạn không muốn cho phép gắn kết thì bạn nên trả về rỗng.</dd>
143  <dt>{@link android.app.Service#onCreate()}</dt>
144    <dd>Hệ thống sẽ gọi phương pháp này khi dịch vụ được tạo lập lần đầu, để thực hiện quy trình thiết lập một lần
145(trước khi nó có thể gọi hoặc {@link android.app.Service#onStartCommand onStartCommand()} hoặc
146{@link android.app.Service#onBind onBind()}). Nếu dịch vụ đã đang chạy, phương pháp này sẽ không được
147gọi.</dd>
148  <dt>{@link android.app.Service#onDestroy()}</dt>
149    <dd>Hệ thống sẽ gọi phương pháp này khi dịch vụ không còn được sử dụng và đang bị hủy.
150Dịch vụ của bạn sẽ triển khai phương pháp này để dọn dẹp mọi tài nguyên như luồng, đối tượng theo dõi
151được đăng ký, hàm nhận, v.v... Đây là lệnh gọi cuối cùng mà dịch vụ nhận được.</dd>
152</dl>
153
154<p>Nếu một thành phần bắt đầu dịch vụ bằng cách gọi {@link
155android.content.Context#startService startService()} (kết quả là một lệnh gọi tới {@link
156android.app.Service#onStartCommand onStartCommand()}), khi đó dịch vụ
157sẽ vẫn chạy tới khi tự nó dừng bằng {@link android.app.Service#stopSelf()} hoặc một
158thành phần khác dừng nó bằng cách gọi {@link android.content.Context#stopService stopService()}.</p>
159
160<p>Nếu một thành phần gọi
161{@link android.content.Context#bindService bindService()} để tạo dịch vụ (và {@link
162android.app.Service#onStartCommand onStartCommand()} <em>không</em> được gọi), khi đó dịch vụ sẽ chỉ chạy
163khi nào mà thành phần đó còn gắn kết với nó. Sau khi dịch vụ được bỏ gắn kết khỏi tất cả máy khách, hệ thống
164sẽ hủy nó.</p>
165
166<p>Hệ thống Android sẽ buộc dừng một dịch vụ chỉ khi bộ nhớ thấp và nó phải khôi phục tài nguyên
167của hệ thống cho hoạt động có tiêu điểm của người dùng. Nếu dịch vụ gắn kết với một hoạt động mà có tiêu điểm
168của người dùng, khi đó sẽ có ít khả năng nó sẽ bị tắt bỏ hơn, và nếu dịch vụ được khai báo là <a href="#Foreground">chạy trong tiền cảnh</a> (đề cập sau), khi đó nó sẽ hầu như không bao giờ bị tắt bỏ.
169Mặt khác, nếu dịch vụ được bắt đầu và chạy trong thời gian dài, hệ thống sẽ hạ thấp vị trí của nó
170trong danh sách tác vụ chạy ngầm qua thời gian và dịch vụ sẽ rất có thể bị
171tắt bỏ&mdash;nếu dịch vụ của bạn được bắt đầu, khi đó bạn phải thiết kế nó để
172xử lý việc khởi động lại do hệ thống một cách uyển chuyển. Nếu hệ thống tắt bỏ dịch vụ của bạn, nó sẽ khởi động lại dịch vụ ngay khi tài nguyên
173có sẵn trở lại (mặc dù điều này cũng phụ thuộc vào giá trị mà bạn trả về từ {@link
174android.app.Service#onStartCommand onStartCommand()}, vấn đề này sẽ được bàn sau). Để biết thêm thông tin
175về thời điểm mà hệ thống có thể hủy một dịch vụ, hãy xem tài liệu <a href="{@docRoot}guide/components/processes-and-threads.html">Tiến trình và Luồng</a>
176.</p>
177
178<p>Trong những phần sau, bạn sẽ thấy cách bạn có thể tạo từng loại dịch vụ và cách sử dụng
179nó từ các thành phần ứng dụng khác.</p>
180
181
182
183<h3 id="Declaring">Khai báo một dịch vụ trong bản kê khai</h3>
184
185<p>Giống như hoạt động (và các thành phần khác), bạn phải khai báo tất cả dịch vụ trong tệp bản kê khai
186của ứng dụng của mình.</p>
187
188<p>Để khai báo dịch vụ của bạn, hãy thêm một phần tử <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> làm
189con của phần tử <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
190. Ví dụ:</p>
191
192<pre>
193&lt;manifest ... &gt;
194  ...
195  &lt;application ... &gt;
196      &lt;service android:name=".ExampleService" /&gt;
197      ...
198  &lt;/application&gt;
199&lt;/manifest&gt;
200</pre>
201
202<p>Xem tham chiếu phần tử <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a>
203để biết thêm thông tin về việc khai báo dịch vụ của bạn trong bản kê khai.</p>
204
205<p>Có các thuộc tính khác mà bạn có thể bao gồm trong phần tử <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> để
206định nghĩa các tính chất chẳng hạn như những quyền cần để bắt đầu dịch vụ và tiến trình mà
207dịch vụ sẽ chạy trong đó. Thuộc tính <a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a>
208là thuộc tính bắt buộc duy nhất&mdash;nó quy định tên lớp của dịch vụ. Một khi
209bạn phát hành ứng dụng của mình, bạn không nên thay đổi tên này, vì nếu bạn làm vậy, bạn sẽ gặp rủi ro làm gãy
210mã do sự phụ thuộc vào các ý định biểu thị để bắt đầu hoặc gắn kết dịch vụ (đọc bài đăng blog, <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Những Điều
211Không Thay Đổi Được</a>).
212
213<p>Để đảm bảo ứng dụng của bạn được bảo mật, <strong>luôn sử dụng một ý định biểu thị khi bắt đầu hoặc gắn kết
214{@link android.app.Service}</strong> của bạn và không được khai báo bộ lọc ý định cho dịch vụ. Nếu
215điều trọng yếu là bạn phải cho phép một chút không rõ ràng về dịch vụ nào sẽ bắt đầu, bạn có thể
216cung cấp bộ lọc ý định cho dịch vụ của mình và loại bỏ tên thành phần khỏi {@link
217android.content.Intent}, nhưng sau đó bạn có thể đặt gói cho ý định bằng {@link
218android.content.Intent#setPackage setPackage()}, điều này cung cấp sự không rõ ràng vừa đủ cho
219dịch vụ mục tiêu đó.</p>
220
221<p>Ngoài ra, bạn có thể đảm bảo rằng dịch vụ của mình chỉ sẵn có cho ứng dụng của bạn bằng cách
222đưa vào thuộc tính <a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
223và đặt nó thành {@code "false"}. Điều này sẽ dừng việc các ứng dụng khác bắt đầu
224dịch vụ của bạn, ngay cả khi sử dụng một ý định biểu thị.</p>
225
226
227
228
229<h2 id="CreatingStartedService">Tạo một Dịch vụ được Bắt đầu</h2>
230
231<p>Dịch vụ được bắt đầu là dịch vụ mà một thành phần khác bắt đầu bằng cách gọi {@link
232android.content.Context#startService startService()}, kết quả là một lệnh gọi tới phương pháp
233{@link android.app.Service#onStartCommand onStartCommand()} của dịch vụ.</p>
234
235<p>Khi một dịch vụ được bắt đầu, nó có một vòng đời độc lập với
236thành phần đã bắt đầu nó và dịch vụ có thể chạy ngầm vô thời hạn, ngay cả khi
237thành phần bắt đầu nó bị hủy. Như vậy, dịch vụ sẽ tự dừng khi làm xong công việc của nó
238bằng cách gọi {@link android.app.Service#stopSelf stopSelf()}, hoặc một thành phần khác có thể dừng nó
239bằng cách gọi {@link android.content.Context#stopService stopService()}.</p>
240
241<p>Một thành phần ứng dụng chẳng hạn như một hoạt động có thể bắt đầu dịch vụ bằng cách gọi {@link
242android.content.Context#startService startService()} và chuyển một {@link android.content.Intent}
243trong đó quy định dịch vụ và bao gồm bất kỳ dữ liệu nào để cho dịch vụ sử dụng. Dịch vụ sẽ nhận
244{@link android.content.Intent} này trong phương pháp {@link android.app.Service#onStartCommand
245onStartCommand()}.</p>
246
247<p>Ví dụ, giả sử một hoạt động cần lưu một số dữ liệu vào cơ sở dữ liệu trực tuyến. Hoạt động có thể
248bắt đầu một dịch vụ đồng hành và truyền cho nó dữ liệu để lưu bằng cách chuyển một ý định tới {@link
249android.content.Context#startService startService()}. Dịch vụ sẽ nhận ý định trong {@link
250android.app.Service#onStartCommand onStartCommand()}, kết nối với Internet và thực hiện
251giao tác cơ sở dữ liệu. Khi giao tác được thực hiện, dịch vụ sẽ tự dừng lại và nó bị
252hủy.</p>
253
254<p class="caution"><strong>Chú ý:</strong> Một dịch vụ sẽ chạy trong cùng tiến trình như ứng dụng
255mà nó được khai báo trong đó và trong luồng chính của ứng dụng đó theo mặc định. Vì vậy, nếu dịch vụ của bạn
256thực hiện các thao tác tăng cường hoặc chặn trong khi người dùng tương tác với một hoạt động từ cùng
257ứng dụng, dịch vụ sẽ làm chậm hiệu năng của hoạt động. Để tránh tác động tới hiệu năng của
258ứng dụng, bạn nên bắt đầu một luồng mới bên trong dịch vụ.</p>
259
260<p>Thông thường, có hai lớp mà bạn có thể mở rộng để tạo một dịch vụ được bắt đầu:</p>
261<dl>
262  <dt>{@link android.app.Service}</dt>
263  <dd>Đây là lớp cơ bản cho tất cả dịch vụ. Khi bạn mở rộng lớp này, điều quan trọng là
264bạn tạo một luồng mới để thực hiện tất cả công việc của dịch vụ trong đó, do dịch vụ sử dụng luồng chính
265của ứng dụng của bạn, theo mặc định, điều này có thể làm chậm hiệu năng của bất kỳ hoạt động nào mà ứng dụng
266của bạn đang chạy.</dd>
267  <dt>{@link android.app.IntentService}</dt>
268  <dd>Đây là một lớp con của {@link android.app.Service} có chức năng sử dụng một luồng trình thực hiện để xử lý tất cả
269yêu cầu bắt đầu một cách lần lượt. Đây là lựa chọn tốt nhất nếu bạn không yêu cầu dịch vụ của mình
270xử lý đồng thời nhiều yêu cầu. Tất cả những gì bạn cần làm đó là triển khai {@link
271android.app.IntentService#onHandleIntent onHandleIntent()}, nó sẽ nhận ý định cho mỗi
272yêu cầu bắt đầu để bạn có thể thực hiện công việc chạy ngầm.</dd>
273</dl>
274
275<p>Các phần sau mô tả cách bạn có thể triển khai dịch vụ của mình bằng cách sử dụng một trong các cách cho những lớp
276này.</p>
277
278
279<h3 id="ExtendingIntentService">Mở rộng lớp IntentService</h3>
280
281<p>Vì phần lớn các dịch vụ được bắt đầu không cần xử lý nhiều yêu cầu một cách đồng thời
282(điều này thực sự có thể là một kịch bản tạo đa luồng nguy hiểm), có lẽ tốt nhất là nếu bạn
283triển khai dịch vụ của mình bằng cách sử dụng lớp {@link android.app.IntentService}.</p>
284
285<p>{@link android.app.IntentService} làm điều sau đây:</p>
286
287<ul>
288  <li>Tạo một luồng trình thực hiện mặc định để thực thi tất cả ý định được chuyển tới {@link
289android.app.Service#onStartCommand onStartCommand()} tách riêng với luồng
290chính của ứng dụng của bạn.</li>
291  <li>Tạo một hàng đợi công việc để chuyển lần lượt từng ý định tới triển khai {@link
292android.app.IntentService#onHandleIntent onHandleIntent()} của bạn, vì thế bạn không bao giờ phải
293lo lắng về vấn đề tạo đa luồng.</li>
294  <li>Dừng dịch vụ sau khi tất cả yêu cầu bắt đầu đều đã được xử lý, vì thế bạn không bao giờ phải gọi
295{@link android.app.Service#stopSelf}.</li>
296  <li>Cung cấp triển khai mặc định của {@link android.app.IntentService#onBind onBind()} mà
297trả về rỗng.</li>
298  <li>Cung cấp triển khai mặc định của {@link android.app.IntentService#onStartCommand
299onStartCommand()} mà gửi ý định tới hàng đợi công việc rồi tới triển khai {@link
300android.app.IntentService#onHandleIntent onHandleIntent()} của bạn.</li>
301</ul>
302
303<p>Tất cả đều nói lên một thực tế rằng tất cả những việc bạn cần làm đó là triển khai {@link
304android.app.IntentService#onHandleIntent onHandleIntent()} để thực hiện công việc mà
305máy khách cung cấp. (Mặc dù bạn cũng cần cung cấp một hàm dựng nhỏ cho dịch vụ.)</p>
306
307<p>Sau đây là ví dụ về triển khai {@link android.app.IntentService}:</p>
308
309<pre>
310public class HelloIntentService extends IntentService {
311
312  /**
313   * A constructor is required, and must call the super {@link android.app.IntentService#IntentService}
314   * constructor with a name for the worker thread.
315   */
316  public HelloIntentService() {
317      super("HelloIntentService");
318  }
319
320  /**
321   * The IntentService calls this method from the default worker thread with
322   * the intent that started the service. When this method returns, IntentService
323   * stops the service, as appropriate.
324   */
325  &#64;Override
326  protected void onHandleIntent(Intent intent) {
327      // Normally we would do some work here, like download a file.
328      // For our sample, we just sleep for 5 seconds.
329      long endTime = System.currentTimeMillis() + 5*1000;
330      while (System.currentTimeMillis() &lt; endTime) {
331          synchronized (this) {
332              try {
333                  wait(endTime - System.currentTimeMillis());
334              } catch (Exception e) {
335              }
336          }
337      }
338  }
339}
340</pre>
341
342<p>Đó là tất cả những gì bạn cần: một hàm dựng và triển khai {@link
343android.app.IntentService#onHandleIntent onHandleIntent()}.</p>
344
345<p>Nếu bạn quyết định cũng khống chế các phương pháp gọi lại khác, chẳng hạn như {@link
346android.app.IntentService#onCreate onCreate()}, {@link
347android.app.IntentService#onStartCommand onStartCommand()}, hoặc {@link
348android.app.IntentService#onDestroy onDestroy()}, hãy nhớ gọi ra siêu triển khai, sao
349cho {@link android.app.IntentService} có thể xử lý hợp lý vòng đời của luồng trình thực hiện.</p>
350
351<p>Ví dụ, {@link android.app.IntentService#onStartCommand onStartCommand()} phải trả về
352triển khai mặc định (đó là cách mà ý định được chuyển tới {@link
353android.app.IntentService#onHandleIntent onHandleIntent()}):</p>
354
355<pre>
356&#64;Override
357public int onStartCommand(Intent intent, int flags, int startId) {
358    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
359    return super.onStartCommand(intent,flags,startId);
360}
361</pre>
362
363<p>Bên cạnh {@link android.app.IntentService#onHandleIntent onHandleIntent()}, phương pháp duy nhất mà
364từ đó bạn không cần gọi siêu lớp là {@link android.app.IntentService#onBind
365onBind()} (nhưng bạn chỉ cần triển khai điều đó nếu dịch vụ của bạn cho phép gắn kết).</p>
366
367<p>Trong phần tiếp theo, bạn sẽ thấy cách mà cùng loại dịch vụ được triển khai khi mở rộng
368lớp {@link android.app.Service} cơ sở, nó có nhiều mã hơn nhưng có thể
369phù hợp nếu bạn cần xử lý các yêu cầu bắt đầu đồng thời.</p>
370
371
372<h3 id="ExtendingService">Mở rộng lớp Dịch vụ</h3>
373
374<p>Như bạn thấy trong phần trước, sử dụng {@link android.app.IntentService} giúp việc
375triển khai một dịch vụ được bắt đầu của bạn trở nên rất đơn giản. Tuy nhiên, nếu bạn cần dịch vụ của mình
376thực hiện tạo đa luồng (thay vì xử lý các yêu cầu bắt đầu thông qua một hàng đợi công việc), khi đó bạn
377có thể mở rộng lớp {@link android.app.Service} để xử lý từng ý định.</p>
378
379<p>Để so sánh, đoạn mã mẫu sau là triển khai lớp {@link
380android.app.Service} mà thực hiện chính xác cùng công việc như ví dụ bên trên bằng cách sử dụng {@link
381android.app.IntentService}. Cụ thể, đối với mỗi yêu cầu bắt đầu, nó sẽ sử dụng một luồng trình thực hiện để thực hiện
382công việc và chỉ xử lý lần lượt từng yêu cầu một.</p>
383
384<pre>
385public class HelloService extends Service {
386  private Looper mServiceLooper;
387  private ServiceHandler mServiceHandler;
388
389  // Handler that receives messages from the thread
390  private final class ServiceHandler extends Handler {
391      public ServiceHandler(Looper looper) {
392          super(looper);
393      }
394      &#64;Override
395      public void handleMessage(Message msg) {
396          // Normally we would do some work here, like download a file.
397          // For our sample, we just sleep for 5 seconds.
398          long endTime = System.currentTimeMillis() + 5*1000;
399          while (System.currentTimeMillis() &lt; endTime) {
400              synchronized (this) {
401                  try {
402                      wait(endTime - System.currentTimeMillis());
403                  } catch (Exception e) {
404                  }
405              }
406          }
407          // Stop the service using the startId, so that we don't stop
408          // the service in the middle of handling another job
409          stopSelf(msg.arg1);
410      }
411  }
412
413  &#64;Override
414  public void onCreate() {
415    // Start up the thread running the service.  Note that we create a
416    // separate thread because the service normally runs in the process's
417    // main thread, which we don't want to block.  We also make it
418    // background priority so CPU-intensive work will not disrupt our UI.
419    HandlerThread thread = new HandlerThread("ServiceStartArguments",
420            Process.THREAD_PRIORITY_BACKGROUND);
421    thread.start();
422
423    // Get the HandlerThread's Looper and use it for our Handler
424    mServiceLooper = thread.getLooper();
425    mServiceHandler = new ServiceHandler(mServiceLooper);
426  }
427
428  &#64;Override
429  public int onStartCommand(Intent intent, int flags, int startId) {
430      Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
431
432      // For each start request, send a message to start a job and deliver the
433      // start ID so we know which request we're stopping when we finish the job
434      Message msg = mServiceHandler.obtainMessage();
435      msg.arg1 = startId;
436      mServiceHandler.sendMessage(msg);
437
438      // If we get killed, after returning from here, restart
439      return START_STICKY;
440  }
441
442  &#64;Override
443  public IBinder onBind(Intent intent) {
444      // We don't provide binding, so return null
445      return null;
446  }
447
448  &#64;Override
449  public void onDestroy() {
450    Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
451  }
452}
453</pre>
454
455<p>Như bạn có thể thấy, có nhiều việc hơn nhiều so với việc sử dụng {@link android.app.IntentService}.</p>
456
457<p>Tuy nhiên, do bạn tự mình xử lý từng lệnh gọi đến {@link android.app.Service#onStartCommand
458onStartCommand()}, bạn có thể thực hiện nhiều yêu cầu một cách đồng thời. Đó không phải là việc
459mà ví dụ này làm, nhưng nếu đó là việc bạn muốn, vậy bạn có thể tạo một luồng mới cho từng
460yêu cầu và ngay lập tức trả chúng về (thay vì đợi tới khi yêu cầu trước hoàn thành).</p>
461
462<p>Để ý rằng phương pháp {@link android.app.Service#onStartCommand onStartCommand()} phải trả về một
463số nguyên. Số nguyên là một giá trị mô tả cách hệ thống nên tiếp tục dịch vụ trong
464trường hợp hệ thống tắt bỏ nó (như được đề cập ở trên, triển khai mặc định cho {@link
465android.app.IntentService} sẽ xử lý điều này cho bạn dù bạn có thể sửa đổi nó). Giá trị trả về
466từ {@link android.app.Service#onStartCommand onStartCommand()} phải là một trong các
467hằng số sau:</p>
468
469<dl>
470  <dt>{@link android.app.Service#START_NOT_STICKY}</dt>
471    <dd>Nếu hệ thống tắt bỏ dịch vụ sau khi {@link android.app.Service#onStartCommand
472onStartCommand()} trả về, <em>không</em> được tạo lại dịch vụ đó, trừ khi có các ý định
473đang chờ để được chuyển. Đây là lựa chọn an toàn nhất để tránh chạy dịch vụ của bạn khi không cần thiết
474và khi ứng dụng của bạn có thể đơn thuần khởi động lại bất kỳ công việc chưa hoàn thành nào.</dd>
475  <dt>{@link android.app.Service#START_STICKY}</dt>
476    <dd>Nếu hệ thống tắt bỏ dịch vụ sau khi {@link android.app.Service#onStartCommand
477onStartCommand()} trả về, hãy tạo lại dịch vụ và gọi {@link
478android.app.Service#onStartCommand onStartCommand()}, nhưng <em>không</em> chuyển lại ý định cuối cùng.
479Thay vào đó, hệ thống sẽ gọi {@link android.app.Service#onStartCommand onStartCommand()} bằng một
480ý định rỗng, trừ khi có các ý định đang chờ để bắt đầu dịch vụ, trong trường hợp đó,
481những ý định này sẽ được chuyển. Điều này phù hợp với các trình phát phương tiện (hoặc dịch vụ tương tự) mà không
482đang thực thi lệnh, nhưng đang chạy vô thời hạn và chờ một tác vụ.</dd>
483  <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt>
484    <dd>Nếu hệ thống tắt bỏ dịch vụ sau khi {@link android.app.Service#onStartCommand
485onStartCommand()} trả về, hãy tạo lại dịch vụ và gọi {@link
486android.app.Service#onStartCommand onStartCommand()} bằng ý định cuối cùng được chuyển tới
487dịch vụ. Mọi ý định chờ đều được chuyển lần lượt. Điều này phù hợp với các dịch vụ đang
488chủ động thực hiện một công việc mà nên được tiếp tục ngay lập tức, chẳng hạn như tải xuống một tệp.</dd>
489</dl>
490<p>Để biết thêm chi tiết về những giá trị trả về này, hãy xem tài liệu tham khảo được liên kết cho từng
491hằng số.</p>
492
493
494
495<h3 id="StartingAService">Bắt đầu một Dịch vụ</h3>
496
497<p>Bạn có thể bắt đầu một dịch vụ từ một hoạt động hoặc thành phần ứng dụng khác bằng cách chuyển một
498{@link android.content.Intent} (quy định dịch vụ sẽ bắt đầu) đến {@link
499android.content.Context#startService startService()}. Hệ thống Android sẽ gọi phương pháp {@link
500android.app.Service#onStartCommand onStartCommand()} của dịch vụ và chuyển cho nó {@link
501android.content.Intent}. (Bạn tuyệt đối không nên trực tiếp gọi {@link android.app.Service#onStartCommand
502onStartCommand()}.)</p>
503
504<p>Ví dụ, một hoạt động có thể bắt đầu dịch vụ ví dụ trong phần trước ({@code
505HelloSevice}) bằng cách sử dụng một ý định biểu thị với {@link android.content.Context#startService
506startService()}:</p>
507
508<pre>
509Intent intent = new Intent(this, HelloService.class);
510startService(intent);
511</pre>
512
513<p>Phương pháp {@link android.content.Context#startService startService()} ngay lập tức trả về và
514hệ thống Android sẽ gọi phương pháp {@link android.app.Service#onStartCommand
515onStartCommand()} của dịch vụ. Nếu dịch vụ không đang chạy, trước tiên hệ thống sẽ gọi {@link
516android.app.Service#onCreate onCreate()}, rồi gọi {@link android.app.Service#onStartCommand
517onStartCommand()}.</p>
518
519<p>Nếu dịch vụ cũng không cung cấp khả năng gắn kết, ý định được chuyển bằng {@link
520android.content.Context#startService startService()} sẽ là phương thức giao tiếp duy nhất giữa
521thành phần ứng dụng và dịch vụ. Tuy nhiên, nếu bạn muốn dịch vụ gửi một kết quả trở lại, khi đó
522máy khách mà bắt đầu dịch vụ có thể tạo một {@link android.app.PendingIntent} cho một quảng bá
523(bằng {@link android.app.PendingIntent#getBroadcast getBroadcast()}) và chuyển nó tới dịch vụ
524trong {@link android.content.Intent} mà bắt đầu dịch vụ. Khi đó, dịch vụ có thể sử dụng
525quảng bá để chuyển kết quả.</p>
526
527<p>Nhiều yêu cầu bắt đầu dịch vụ sẽ dẫn đến nhiều lệnh gọi tương ứng tới
528{@link android.app.Service#onStartCommand onStartCommand()} của dịch vụ. Tuy nhiên, chỉ có một yêu cầu dừng
529dịch vụ (bằng {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
530android.content.Context#stopService stopService()}) là bắt buộc để dừng nó.</p>
531
532
533<h3 id="Stopping">Dừng một dịch vụ</h3>
534
535<p>Dịch vụ được bắt đầu phải quản lý vòng đời của chính nó. Cụ thể, hệ thống không dừng
536hay hủy dịch vụ trừ khi nó phải khôi phục bộ nhớ của hệ thống và dịch vụ
537sẽ tiếp tục chạy sau khi {@link android.app.Service#onStartCommand onStartCommand()} trả về. Vì vậy,
538dịch vụ phải tự dừng bằng cách gọi {@link android.app.Service#stopSelf stopSelf()} hoặc một thành phần
539khác có thể dừng nó bằng cách gọi {@link android.content.Context#stopService stopService()}.</p>
540
541<p>Sau khi được yêu cầu dừng bằng {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
542android.content.Context#stopService stopService()}, hệ thống sẽ hủy dịch vụ ngay khi
543có thể.</p>
544
545<p>Tuy nhiên, nếu dịch vụ của bạn xử lý nhiều yêu cầu {@link
546android.app.Service#onStartCommand onStartCommand()} đồng thời, khi đó bạn không nên dừng
547dịch vụ khi bạn đã hoàn thành xử lý yêu cầu bắt đầu, vì bạn có thể đã nhận được một
548yêu cầu bắt đầu mới kể từ thời điểm đó (dừng khi kết thúc yêu cầu thứ nhất sẽ chấm dứt yêu cầu thứ hai). Để tránh
549vấn đề này, bạn có thể sử dụng {@link android.app.Service#stopSelf(int)} để đảm bảo rằng yêu cầu
550dừng dịch vụ của bạn luôn được dựa trên yêu cầu bắt đầu gần đây nhất. Cụ thể, khi bạn gọi {@link
551android.app.Service#stopSelf(int)}, bạn sẽ chuyển ID của yêu cầu bắt đầu (<code>startId</code>
552được chuyển tới {@link android.app.Service#onStartCommand onStartCommand()}) mà yêu cầu dừng của bạn
553tương ứng với. Khi đó, nếu dịch vụ đã nhận được một yêu cầu bắt đầu mới trước khi bạn có thể gọi {@link
554android.app.Service#stopSelf(int)}, vậy ID sẽ không khớp và dịch vụ sẽ không dừng.</p>
555
556<p class="caution"><strong>Chú ý:</strong> Điều quan trọng là ứng dụng của bạn dừng dịch vụ của nó
557khi nó hoàn thành xong công việc để tránh lãng phí tài nguyên của hệ thống và tốn pin. Nếu cần,
558các thành phần khác có thể dừng dịch vụ bằng cách gọi {@link
559android.content.Context#stopService stopService()}. Ngay cả khi bạn kích hoạt gắn kết cho dịch vụ,
560bạn phải luôn tự mình dừng dịch vụ nếu dịch vụ đã nhận được lệnh gọi tới {@link
561android.app.Service#onStartCommand onStartCommand()}.</p>
562
563<p>Để biết thêm thông tin về vòng đời của một dịch vụ, hãy xem phần bên dưới về <a href="#Lifecycle">Quản lý Vòng đời của một Dịch vụ</a>.</p>
564
565
566
567<h2 id="CreatingBoundService">Tạo một Dịch vụ Gắn kết</h2>
568
569<p>Dịch vụ gắn kết là một dịch vụ cho phép các thành phần ứng dụng gắn kết với nó bằng cách gọi {@link
570android.content.Context#bindService bindService()} để tạo một kết nối lâu dài
571(và thường không cho phép các thành phần <em>bắt đầu</em> nó bằng cách gọi {@link
572android.content.Context#startService startService()}).</p>
573
574<p>Bạn nên tạo một dịch vụ gắn kết khi muốn tương tác với dịch vụ từ hoạt động
575và các thành phần khác trong ứng dụng của mình hoặc để hiển thị một số tính năng trong ứng dụng của bạn cho
576các ứng dụng khác thông qua truyền thông liên tiến trình (IPC).</p>
577
578<p>Để tạo một dịch vụ gắn kết, bạn phải triển khai phương pháp gọi lại {@link
579android.app.Service#onBind onBind()} để trả về một {@link android.os.IBinder} mà
580định nghĩa giao diện cho giao tiếp với dịch vụ đó. Khi đó, các thành phần ứng dụng khác có thể gọi
581{@link android.content.Context#bindService bindService()} để truy xuất giao diện và
582bắt đầu các phương pháp gọi trên dịch vụ. Dịch vụ tồn tại chỉ nhằm phục vụ thành phần ứng dụng mà
583được gắn kết với nó, vì thế khi không có thành phần được gắn kết với dịch vụ, hệ thống sẽ hủy nó
584(bạn <em>không</em> cần dừng một dịch vụ gắn kết theo cách phải làm khi dịch vụ được bắt đầu
585thông qua {@link android.app.Service#onStartCommand onStartCommand()}).</p>
586
587<p>Để tạo một dịch vụ gắn kết, điều đầu tiên bạn phải làm là định nghĩa giao diện quy định
588cách thức mà một máy khách có thể giao tiếp với dịch vụ. Giao diện giữa dịch vụ và
589máy khách này phải là một triển khai {@link android.os.IBinder} và được dịch vụ của bạn phải
590trả về từ phương pháp gọi lại {@link android.app.Service#onBind
591onBind()}. Sau khi máy khách nhận được {@link android.os.IBinder}, nó có thể bắt đầu
592tương tác với dịch vụ thông qua giao diện đó.</p>
593
594<p>Nhiều máy khách có thể gắn kết với dịch vụ đồng thời. Khi một máy khách hoàn thành tương tác với
595dịch vụ, nó sẽ gọi {@link android.content.Context#unbindService unbindService()} để bỏ gắn kết. Sau khi
596không còn máy khách nào được gắn kết với dịch vụ, hệ thống sẽ hủy dịch vụ.</p>
597
598<p>Có nhiều cách để triển khai một dịch vụ gắn kết và triển khai sẽ phức tạp
599hơn so với dịch vụ được bắt đầu, vì thế nội dung bàn về dịch vụ gắn kết được trình bày trong một
600tài liệu riêng về <a href="{@docRoot}guide/components/bound-services.html">Dịch vụ Gắn kết</a>.</p>
601
602
603
604<h2 id="Notifications">Gửi Thông báo tới Người dùng</h2>
605
606<p>Sau khi chạy, một dịch vụ có thể thông báo cho người dùng về sự kiện bằng cách sử dụng <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Thông báo Cửa sổ</a> hoặc <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo Thanh Trạng thái</a>.</p>
607
608<p>Thông báo cửa sổ là một thông báo xuất hiện một lúc trên bề mặt của cửa sổ hiện tại
609rồi biến mất, trong khi thông báo thanh trạng thái cung cấp một biểu tượng trong thanh trạng thái cùng một
610thông báo, người dùng có thể chọn nó để thực hiện một hành động (chẳng hạn như bắt đầu một hoạt động).</p>
611
612<p>Thông thường thông báo thanh trạng thái là kỹ thuật tốt nhất khi một công việc nền nào đó đã hoàn thành
613(chẳng hạn như một tệp đã hoàn thành
614việc tải xuống) và lúc này người dùng có thể hành động dựa trên nó. Khi người dùng chọn thông báo từ dạng xem mở rộng
615, thông báo có thể bắt đầu một hoạt động (chẳng hạn như xem tệp được tải xuống).</p>
616
617<p>Xem hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Thông báo Cửa sổ</a> hoặc <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo Thanh Trạng thái</a>
618để biết thêm thông tin.</p>
619
620
621
622<h2 id="Foreground">Chạy một Dịch vụ trong Tiền cảnh</h2>
623
624<p>Dịch vụ tiền cảnh là một dịch vụ được coi là điều mà
625người dùng đang chủ động quan tâm, vì thế nó không được đề nghị để hệ thống tắt bỏ khi bộ nhớ thấp. Dịch vụ
626tiền cảnh phải cung cấp một thông báo cho thanh trạng thái, nó được đặt dưới tiêu đề
627"Đang diễn ra", điều này có nghĩa là thông báo không thể loại bỏ được trừ khi dịch vụ
628bị dừng hoặc loại bỏ khỏi tiền cảnh.</p>
629
630<p>Ví dụ, một trình chơi nhạc đang phát nhạc từ một dịch vụ nên được đặt để chạy trong
631tiền cảnh, vì người dùng rõ ràng ý thức được
632hoạt động của nó. Thông báo trong thanh trạng thái có thể cho biết bài hát đang chơi và cho phép
633người dùng khởi chạy một hoạt động để tương tác với trình chơi nhạc.</p>
634
635<p>Để yêu cầu dịch vụ của bạn chạy trong tiền cảnh, hãy gọi {@link
636android.app.Service#startForeground startForeground()}. Phương pháp này dùng hai tham số: một số nguyên
637để xác định duy nhất thông báo và {@link
638android.app.Notification} cho thanh trạng thái. Ví dụ:</p>
639
640<pre>
641Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
642        System.currentTimeMillis());
643Intent notificationIntent = new Intent(this, ExampleActivity.class);
644PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
645notification.setLatestEventInfo(this, getText(R.string.notification_title),
646        getText(R.string.notification_message), pendingIntent);
647startForeground(ONGOING_NOTIFICATION_ID, notification);
648</pre>
649
650<p class="caution"><strong>Chú ý:</strong> ID số nguyên mà bạn cấp cho {@link
651android.app.Service#startForeground startForeground()} không được bằng 0.</p>
652
653
654<p>Để xóa bỏ dịch vụ khỏi tiền cảnh, hãy gọi {@link
655android.app.Service#stopForeground stopForeground()}. Phương pháp này dùng một boolean, cho biết
656có loại bỏ cả thông báo thanh trạng thái hay không. Phương pháp này <em>không</em> dừng
657dịch vụ. Tuy nhiên, nếu bạn dừng dịch vụ trong khi nó vẫn đang chạy trong tiền cảnh, khi đó thông báo
658cũng bị loại bỏ.</p>
659
660<p>Để biết thêm thông tin về thông báo, hãy xem phần <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Tạo Thông báo
661Thanh Trạng thái</a>.</p>
662
663
664
665<h2 id="Lifecycle">Quản lý Vòng đời của một Dịch vụ</h2>
666
667<p>Vòng đời của một dịch vụ đơn giản hơn nhiều so với vòng đời của một hoạt động. Tuy nhiên, một điều thậm chí còn quan trọng hơn
668đó là bạn phải thật chú ý tới cách dịch vụ của bạn được tạo và hủy, bởi một dịch vụ
669có thể chạy ngầm mà người dùng không biết.</p>
670
671<p>Vòng đời của dịch vụ&mdash;từ khi nó được tạo tới khi nó bị hủy&mdash;có thể đi theo hai
672con đường khác nhau:</p>
673
674<ul>
675<li>Dịch vụ được bắt đầu
676  <p>Dịch vụ được tạo khi một thành phần khác gọi {@link
677android.content.Context#startService startService()}. Sau đó, dịch vụ sẽ chạy vô thời hạn và phải
678tự dừng bằng cách gọi {@link
679android.app.Service#stopSelf() stopSelf()}. Một thành phần khác cũng có thể dừng
680dịch vụ bằng cách gọi {@link android.content.Context#stopService
681stopService()}. Khi dịch vụ bị dừng, hệ thống sẽ hủy nó.</p></li>
682
683<li>Dịch vụ gắn kết
684  <p>Dịch vụ được tạo khi một thành phần khác (máy khách) gọi {@link
685android.content.Context#bindService bindService()}. Khi đó, máy khách giao tiếp với dịch vụ
686thông qua một giao diện {@link android.os.IBinder}. Máy khách có thể đóng kết nối bằng cách gọi
687{@link android.content.Context#unbindService unbindService()}. Nhiều máy khách có thể gắn kết với
688cùng dịch vụ và khi tất cả chúng bỏ gắn kết, hệ thống sẽ hủy dịch vụ. (Dịch vụ
689<em>không</em> cần tự mình dừng.)</p></li>
690</ul>
691
692<p>Hai con đường này hoàn toàn riêng biệt. Cụ thể, bạn có thể gắn kết với một dịch vụ đã
693được bắt đầu bằng {@link android.content.Context#startService startService()}. Ví dụ, một dịch vụ
694nhạc nền có thể được bắt đầu bằng cách gọi {@link android.content.Context#startService
695startService()} bằng một {@link android.content.Intent} mà sẽ nhận biết nhạc để phát. Sau đó,
696có thể là khi người dùng muốn thực thi một quyền điều khiển đối với trình phát đó hoặc lấy thông tin về
697bài hát đang phát, hoạt động có thể gắn kết với dịch vụ bằng cách gọi {@link
698android.content.Context#bindService bindService()}. Trong những trường hợp như vậy, {@link
699android.content.Context#stopService stopService()} hoặc {@link android.app.Service#stopSelf
700stopSelf()} không thực sự dừng dịch vụ tới khi tất cả máy khách bỏ gắn kết. </p>
701
702
703<h3 id="LifecycleCallbacks">Triển khai gọi lại vòng đời</h3>
704
705<p>Giống như một hoạt động, dịch vụ có các phương pháp gọi lại vòng đời mà bạn có thể triển khai để theo dõi
706những thay đổi về trạng thái của dịch vụ và thực hiện công việc tại những thời điểm phù hợp. Dịch vụ khung sau
707minh họa từng phương pháp vòng đời:</p>
708
709<pre>
710public class ExampleService extends Service {
711    int mStartMode;       // indicates how to behave if the service is killed
712    IBinder mBinder;      // interface for clients that bind
713    boolean mAllowRebind; // indicates whether onRebind should be used
714
715    &#64;Override
716    public void {@link android.app.Service#onCreate onCreate}() {
717        // The service is being created
718    }
719    &#64;Override
720    public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) {
721        // The service is starting, due to a call to {@link android.content.Context#startService startService()}
722        return <em>mStartMode</em>;
723    }
724    &#64;Override
725    public IBinder {@link android.app.Service#onBind onBind}(Intent intent) {
726        // A client is binding to the service with {@link android.content.Context#bindService bindService()}
727        return <em>mBinder</em>;
728    }
729    &#64;Override
730    public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
731        // All clients have unbound with {@link android.content.Context#unbindService unbindService()}
732        return <em>mAllowRebind</em>;
733    }
734    &#64;Override
735    public void {@link android.app.Service#onRebind onRebind}(Intent intent) {
736        // A client is binding to the service with {@link android.content.Context#bindService bindService()},
737        // after onUnbind() has already been called
738    }
739    &#64;Override
740    public void {@link android.app.Service#onDestroy onDestroy}() {
741        // The service is no longer used and is being destroyed
742    }
743}
744</pre>
745
746<p class="note"><strong>Lưu ý:</strong> Không như các phương pháp gọi lại vòng đời của hoạt động, bạn
747<em>không</em> phải gọi triển khai siêu lớp với những phương pháp gọi lại này.</p>
748
749<img src="{@docRoot}images/service_lifecycle.png" alt="" />
750<p class="img-caption"><strong>Hình 2.</strong> Vòng đời dịch vụ. Sơ đồ phía bên trái
751minh họa vòng đời khi dịch vụ được tạo bằng {@link android.content.Context#startService
752startService()} và sơ đồ phía bên phải minh họa vòng đời khi dịch vụ được tạo
753bằng {@link android.content.Context#bindService bindService()}.</p>
754
755<p>Bằng việc triển khai những phương pháp này, bạn có thể theo dõi hai vòng lặp lồng nhau trong vòng đời của dịch vụ: </p>
756
757<ul>
758<li><strong>Toàn bộ vòng đời</strong> của một dịch vụ xảy ra giữa thời điểm gọi {@link
759android.app.Service#onCreate onCreate()} và thời điểm {@link
760android.app.Service#onDestroy} trả về. Giống như hoạt động, dịch vụ thực hiện thiết lập ban đầu của nó trong
761{@link android.app.Service#onCreate onCreate()} và giải phóng tất cả tài nguyên còn lại trong {@link
762android.app.Service#onDestroy onDestroy()}.  Ví dụ, một
763dịch vụ phát lại nhạc có thể tạo luồng mà tại đó nhạc sẽ được phát trong {@link
764android.app.Service#onCreate onCreate()}, sau đó dừng luồng trong {@link
765android.app.Service#onDestroy onDestroy()}.
766
767<p>Các phương pháp {@link android.app.Service#onCreate onCreate()} và {@link android.app.Service#onDestroy
768onDestroy()} được gọi cho tất cả dịch vụ, dù
769chúng được tạo bởi {@link android.content.Context#startService startService()} hay {@link
770android.content.Context#bindService bindService()}.</p></li>
771
772<li><strong>Vòng đời hiện hoạt</strong> của một dịch vụ sẽ bắt đầu bằng một lệnh gọi đến hoặc {@link
773android.app.Service#onStartCommand onStartCommand()} hoặc {@link android.app.Service#onBind onBind()}.
774Mỗi phương pháp sẽ được giao {@link
775android.content.Intent} mà được chuyển tương ứng cho hoặc {@link android.content.Context#startService
776startService()} hoặc {@link android.content.Context#bindService bindService()}.
777<p>Nếu dịch vụ được bắt đầu, vòng đời hiện hoạt sẽ chấm dứt tại cùng thời điểm khi toàn bộ vòng đời
778chấm dứt (dịch vụ sẽ vẫn hiện hoạt ngay cả sau khi {@link android.app.Service#onStartCommand
779onStartCommand()} trả về). Nếu dịch vụ bị gắn kết, vòng đời hiện hoạt sẽ chấm dứt khi {@link
780android.app.Service#onUnbind onUnbind()} trả về.</p>
781</li>
782</ul>
783
784<p class="note"><strong>Lưu ý:</strong> Mặc dù dịch vụ được bắt đầu bị dừng bởi một lệnh gọi đến
785hoặc {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
786android.content.Context#stopService stopService()}, sẽ không có một lệnh gọi lại tương ứng cho
787dịch vụ (không có lệnh gọi lại {@code onStop()}). Vì thế, trừ khi dịch vụ được gắn kết với một máy khách,
788hệ thống sẽ hủy nó khi dịch vụ bị dừng&mdash;{@link
789android.app.Service#onDestroy onDestroy()} là lệnh gọi lại duy nhất nhận được.</p>
790
791<p>Hình 2 minh họa các phương pháp gọi lại điển hình cho một dịch vụ. Mặc dù hình tách riêng
792các dịch vụ được tạo bởi {@link android.content.Context#startService startService()} với các dịch vụ
793được tạo bởi {@link android.content.Context#bindService bindService()}, hãy
794ghi nhớ rằng bất kỳ dịch vụ nào, dù được bắt đầu như thế nào, đều có thể cho phép máy khách gắn kết với nó.
795Vì thế, một dịch vụ được bắt đầu từ đầu bằng {@link android.app.Service#onStartCommand
796onStartCommand()} (bởi một máy khách gọi {@link android.content.Context#startService startService()})
797vẫn có thể nhận một lệnh gọi đến {@link android.app.Service#onBind onBind()} (khi máy khách gọi
798{@link android.content.Context#bindService bindService()}).</p>
799
800<p>Để biết thêm thông tin về việc tao một dịch vụ có tính năng gắn kết, hãy xem tài liệu <a href="{@docRoot}guide/components/bound-services.html">Dịch vụ Gắn kết</a>,
801trong đó có thêm thông tin về phương pháp gọi lại {@link android.app.Service#onRebind onRebind()}
802trong phần về <a href="{@docRoot}guide/components/bound-services.html#Lifecycle">Quản lý Vòng đời của
803một Dịch vụ Gắn kết</a>.</p>
804
805
806<!--
807<h2>Beginner's Path</h2>
808
809<p>To learn how to query data from the system or other applications (such as contacts or media
810stored on the device), continue with the <b><a
811href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b>
812document.</p>
813-->
814