Dịch vụ so với IntentService trong nền tảng Android


774

Tôi đang tìm kiếm một ví dụ về một cái gì đó có thể được thực hiện với một IntentServicethứ không thể được thực hiện với một Service(và ngược lại)?

Tôi cũng tin rằng một IntentServicechạy trong một chủ đề khác và một Servicekhông. Vì vậy, theo như tôi có thể thấy, bắt đầu một dịch vụ trong luồng của chính nó cũng giống như bắt đầu một IntentService. Đúng không?


45
IntentService is used for short tasks (etc) and a service is for long onesbạn đọc những thứ đó ở đâu ?
njzk2

9
Ngoài ra, tôi khuyên bạn nên đọc mã nguồn cho IntentService. Nó làm cho nó khá rõ ràng nó là gì và nó làm gì.
njzk2

1
Tôi đã chỉnh sửa câu hỏi của tôi sau khi tôi thấy bạn bình luận.
roiberg


2
Liên kết trong nhận xét trước (bởi greg7gkb) là một bài đọc tuyệt vời.
DSlomer64

Câu trả lời:


1348

Tejas Lagvankar đã viết một bài đăng hay về chủ đề này. Dưới đây là một số khác biệt chính giữa Dịch vụ và IntentService.

Khi nào sử dụng?

  • Các dịch vụ có thể được sử dụng trong các nhiệm vụ không có giao diện người dùng, nhưng không nên quá dài. Nếu bạn cần thực hiện các tác vụ dài, bạn phải sử dụng các luồng trong Dịch vụ.

  • Các IntentService có thể được sử dụng trong các nhiệm vụ dài thường không có thông tin liên lạc để chính Chủ đề. Nếu cần liên lạc, có thể sử dụng trình xử lý Main Thread hoặc ý định phát sóng. Một trường hợp sử dụng khác là khi cần gọi lại (Nhiệm vụ kích hoạt ý định).

Làm thế nào để kích hoạt?

  • Các dịch vụ được kích hoạt bằng phương pháp gọi startService().

  • Các IntentService được kích hoạt sử dụng Intent, nó sinh ra một sợi công nhân mới và phương pháp onHandleIntent()được gọi vào chủ đề này.

Kích hoạt từ

  • Các dịch vụIntentService thể được kích hoạt từ bất kỳ chủ đề, hoạt động hoặc một thành phần ứng dụng khác.

Chạy đi

  • Các dịch vụ chạy ở chế độ nền nhưng nó chạy trên các chủ đề chính của ứng dụng.

  • Các IntentService chạy trên một sợi công nhân riêng biệt.

Hạn chế / nhược điểm

  • Các dịch vụ có thể chặn các Chủ đề chính của ứng dụng.

  • Các IntentService không thể chạy các tác vụ song song. Do đó, tất cả các ý định liên tiếp sẽ đi vào hàng đợi tin nhắn cho luồng worker và sẽ thực thi tuần tự.

Khi nào thì dừng?

  • Nếu bạn triển khai Dịch vụ , bạn có trách nhiệm dừng dịch vụ khi công việc được hoàn thành, bằng cách gọi stopSelf()hoặc stopService(). (Nếu bạn chỉ muốn cung cấp ràng buộc, bạn không cần phải thực hiện phương pháp này).

  • Dịch vụ IntentService dừng các dịch vụ sau khi tất cả các yêu cầu khởi động đã được xử lý, vì vậy bạn không bao giờ phải gọi stopSelf().


11
ngắn gọn và ngọt ngào, nhưng sẽ tốt hơn nếu bạn chỉnh sửa câu trả lời của mình bao gồm các điểm của CommonsWare, vì nhiều người chỉ đọc các câu trả lời được chấp nhận hoặc được đánh giá cao nhất
Shirish Herwade

12
@Darpan Dịch vụ là một thành phần ứng dụng có thể thực hiện các hoạt động chạy dài trong nền và không cung cấp giao diện người dùng. Một dịch vụ chạy trong luồng chính của quá trình lưu trữ. Dịch vụ không tạo luồng riêng và không chạy trong một quy trình riêng (trừ khi bạn chỉ định khác). Điều này có nghĩa là, nếu dịch vụ của bạn sẽ thực hiện bất kỳ hoạt động chuyên sâu nào của CPU hoặc chặn các hoạt động (như phát lại MP3 hoặc kết nối mạng), bạn nên tạo một luồng mới trong dịch vụ để thực hiện công việc đó.
Jose Juan Sánchez

8
"IntentService phải được kích hoạt từ Chủ đề chính." Bạn có chắc không? Bên trong MainActivity onCreate () của tôi, khi tôi gọi một IntentService từ một Chủ đề mới (mã bên dưới), nó vẫn hoạt động với tôi. chủ đề mới (new Runnable () {@Override public void run () {Intent aim = new Intent (bối cảnh, HelloIntentService. class); startService (ý định);}}). start ();
Ashok Bijoy Debnath

9
@AshokBijoyDebnath Bạn nói đúng! Các dịch vụIntentServices có thể được bắt đầu từ bất kỳ chủ đề, hoạt động hoặc một thành phần ứng dụng khác. Tôi vừa chỉnh sửa văn bản của câu trả lời để khắc phục vấn đề này. Cảm ơn bạn đã đề nghị chỉnh sửa của bạn! :)
Jose Juan Sánchez

2
Không có vấn đề, đi cho nó!
Jose Juan Sánchez

165

Nếu ai đó có thể chỉ cho tôi một ví dụ về một cái gì đó có thể được thực hiện với một IntentServicevà không thể được thực hiện với một Servicevà cách khác.

Theo định nghĩa, đó là điều không thể. IntentServicelà một lớp con của Service, được viết bằng Java. Do đó, bất cứ điều gì IntentServicelàm, một Servicecó thể làm, bằng cách bao gồm các bit mã có liên quan IntentServicesử dụng.

Bắt đầu một dịch vụ với luồng riêng của nó giống như bắt đầu một IntentService. Không phải nó?

Ba tính năng chính của một IntentServicelà:

  • chủ đề nền

  • việc xếp hàng tự động của Intents được gửi tới onStartCommand(), vì vậy nếu một lệnh Intentđang được xử lý onHandleIntent()trên luồng nền, các lệnh khác sẽ xếp hàng chờ đến lượt

  • tự động tắt IntentService, thông qua một cuộc gọi đến stopSelf(), khi hàng đợi trống

Bất kỳ và tất cả điều đó có thể được thực hiện bởi một Servicemà không cần mở rộng IntentService.


6
Một chút trễ, nhưng tôi thấy rằng Servicegọi với startServicechỉ có thể chạy trong khoảng 10 giây trước khi ném một ANR-- một IntentServicebắt đầu với phát sóng một ý định dường như không có giới hạn này
edthethird

16
@edthethird: Đó là bởi vì bạn đã buộc chủ đề ứng dụng chính. Tất cả các phương thức vòng đời trên tất cả các thành phần, bao gồm onStartCommand()a Service, được gọi trên luồng ứng dụng chính. Bạn không thể buộc chuỗi này trong hơn một vài mili giây mà không đóng băng giao diện người dùng của mình và nếu bạn mất nhiều giây, bạn sẽ nhận được dịch vụ tương đương với ANR.
CommonsWare

3
yup tôi nhận xét quá sớm. Tôi đã thực hiện công việc onStartCommandthay vì onHandleIntent- có vẻ như onStartCommandđược chạy trên luồng UI, tuy nhiên một luồng riêng biệt được sinh ra để onHandleIntentthực thi.
edthethird

3
@IgorGanapolsky: IntentServicegọi chính nó, sau khi onHandleIntent()trả về, nếu không có nhiều việc phải làm.
CommonsWare 27/1/2015

1
Vấn đề không phải là tiếng Anh, mà là lập trình. Ví dụ: "tôi đã ĐÓNG ứng dụng" không có định nghĩa chính xác, vì vậy tôi không thể cho bạn biết điều gì xảy ra khi điều đó xảy ra. Tôi cũng không biết làm thế nào "tôi đã ĐÓNG ứng dụng" liên quan đến "sẽ tải xuống sau 1 giờ". Bạn có thể cân nhắc đặt câu hỏi Stack Overflow riêng biệt, nơi bạn có thể cung cấp một ví dụ có thể lặp lại tối thiểu về "sẽ tải xuống sau 1 giờ". Ở đó, bạn có thể giải thích chi tiết "tôi đã ĐÓNG ứng dụng" nghĩa là gì (ví dụ, người dùng đặc biệt làm gì để đóng ứng dụng?).
CommonsWare

39

Dịch vụ

  • Gọi bằng startService()
  • Kích hoạt từ bất kỳ Thread
  • Chạy vào Main Thread
  • Có thể chặn luồng chính (UI). Luôn sử dụng luồng trong dịch vụ cho nhiệm vụ dài
  • Khi nhiệm vụ đã hoàn thành, chúng tôi có trách nhiệm dừng dịch vụ bằng cách gọi stopSelf()hoặcstopService()

Dịch vụ ý định

  • Nó thực hiện nhiệm vụ dài thường không có giao tiếp với luồng chính nếu cần giao tiếp thì nó được thực hiện bởi HandlerhoặcBroadcastReceiver
  • Gọi qua Intent
  • Kích hoạt từ Main Thread
  • Chạy trên luồng riêng biệt
  • Không thể chạy tác vụ song song và nhiều ý định được xếp hàng trên cùng một luồng công nhân.

19

Đừng phát minh lại bánh xe

IntentService mở rộng lớp Dịch vụ , điều đó có nghĩa rõ ràng là IntentServiceđược cố ý thực hiện cho cùng mục đích .

Vậy mục đích là gì?

Mục đích của IntentService là làm cho công việc của chúng tôi dễ dàng hơn để chạy các tác vụ nền mà không phải lo lắng về

  • Tạo chủ đề công nhân

  • Xếp hàng xử lý nhiều yêu cầu từng cái một ( Threading)

  • Phá hủy Service

Vì vậy, KHÔNG , Servicecó thể làm bất kỳ nhiệm vụ mà một IntentServicesẽ làm. Nếu các yêu cầu của bạn nằm trong các tiêu chí nêu trên, thì bạn không cần phải viết những logic đó trong Servicelớp. Vì vậy, đừng phát minh lại bánh xe vì IntentServicelà bánh xe được phát minh.

Sự khác biệt chính

Dịch vụ chạy trên luồng UI trong khi IntentService chạy trên một luồng riêng

Khi nào bạn sử dụng IntentService?

Khi bạn muốn thực hiện nhiều tác vụ nền lần lượt từng phần vượt quá phạm vi của Hoạt động thì điều đó IntentServicelà hoàn hảo.

IntentServiceđược làm từService

Một dịch vụ bình thường chạy trên Chủ đề giao diện người dùng (Bất kỳ loại Thành phần Android nào cũng chạy trên chủ đề UI theo mặc định Activity, ví dụ BroadcastReceiver, ContentProviderService). Nếu bạn phải thực hiện một số công việc có thể mất một lúc để hoàn thành thì bạn phải tạo một chủ đề. Trong trường hợp có nhiều yêu cầu, bạn sẽ phải giải quyết synchronization. IntentServiceđược đưa ra một số thực hiện mặc định thực hiện những nhiệm vụ đó cho bạn.
Theo trang nhà phát triển

  1. IntentService tạo ra một chủ đề công nhân

  2. IntentServicetạo một hàng đợi công việc gửi yêu cầu đến onHandleIntent()phương thức từng cái một

  3. Khi không có việc thì IntentServicegọi.stopSelf() phương thức
  4. Cung cấp triển khai mặc định cho onBind()phương thức null
  5. Triển khai mặc định onStartCommand()gửi Intentyêu cầu tới WorkQueue và cuối cùng tớionHandleIntent()

15

Thêm điểm vào câu trả lời được chấp nhận:

Xem cách sử dụng IntentService trong API Android. ví dụ:

public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {  ...}

Để tạo thành phần IntentService cho ứng dụng của bạn, hãy xác định một lớp mở rộng IntentService và trong đó, xác định một phương thức ghi đè onHandleIntent ().

Ngoài ra, hãy xem mã nguồn của IntentService, đó là phương thức xây dựng và vòng đời như onStartCommand ...

  @Override
    public int More ...onStartCommand(Intent intent, int flags, int startId) {
       onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

Dịch vụ cùng với AsyncTask là một trong những cách tiếp cận tốt nhất cho nhiều trường hợp sử dụng trong đó tải trọng không lớn. hoặc chỉ tạo một lớp mở rộng IntentSerivce. Từ phiên bản Android 4.0, tất cả các hoạt động mạng phải ở trong quá trình nền nếu không ứng dụng biên dịch / xây dựng không thành công. chủ đề riêng biệt từ UI. Lớp AsyncTask cung cấp một trong những cách đơn giản nhất để thực hiện một tác vụ mới từ luồng UI. Để thảo luận thêm về chủ đề này, xem bài viết trên blog

từ hướng dẫn dành cho nhà phát triển Android :

IntentService là một lớp cơ sở cho các Dịch vụ xử lý các yêu cầu không đồng bộ (được biểu thị dưới dạng Ý định) theo yêu cầu. Khách hàng gửi yêu cầu thông qua các cuộc gọi startService (Ý định); dịch vụ được bắt đầu khi cần thiết, lần lượt xử lý từng Intent, sử dụng luồng công nhân và tự dừng khi hết công việc.

Mẫu thiết kế được sử dụng trong IntentService

: Mẫu "bộ xử lý hàng đợi công việc" này thường được sử dụng để giảm tải các tác vụ từ luồng chính của ứng dụng. Lớp IntentService tồn tại để đơn giản hóa mẫu này và chăm sóc các cơ chế. Để sử dụng nó, hãy mở rộng IntentService và triển khai onHandleIntent (Intent). IntentService sẽ nhận được Ý định, khởi chạy một luồng công nhân và dừng dịch vụ khi thích hợp.

Tất cả các yêu cầu được xử lý trên một luồng công nhân duy nhất - chúng có thể mất chừng nào cần thiết (và sẽ không chặn vòng lặp chính của ứng dụng), nhưng mỗi lần chỉ có một yêu cầu sẽ được xử lý.

Lớp IntentService cung cấp một cấu trúc đơn giản để chạy một hoạt động trên một luồng nền đơn. Điều này cho phép nó xử lý các hoạt động dài mà không ảnh hưởng đến khả năng phản hồi của giao diện người dùng của bạn. Ngoài ra, một IntentService không bị ảnh hưởng bởi hầu hết các sự kiện vòng đời giao diện người dùng, do đó, nó tiếp tục chạy trong các trường hợp sẽ tắt AsyncTask.

Một IntentService có một vài hạn chế:

Nó không thể tương tác trực tiếp với giao diện người dùng của bạn. Để đưa kết quả của nó vào UI, bạn phải gửi chúng đến một Hoạt động. Yêu cầu công việc chạy tuần tự. Nếu một hoạt động đang chạy trong IntentService và bạn gửi yêu cầu khác, yêu cầu sẽ đợi cho đến khi hoạt động đầu tiên kết thúc. Một hoạt động chạy trên IntentService không thể bị gián đoạn. Tuy nhiên, trong hầu hết các trường hợp

IntentService là cách ưa thích cho các hoạt động nền đơn giản

**

Thư viện Volley

Có một thư viện gọi là thư viện bóng chuyền để phát triển các ứng dụng mạng Android Mã nguồn có sẵn cho công chúng trong GitHub.

Tài liệu chính thức của Android về Thực tiễn tốt nhất cho các công việc Nền : giúp hiểu rõ hơn về dịch vụ mục đích, luồng, xử lý, dịch vụ. và cũng thực hiện các hoạt động mạng


1
Nó có thể tốt hơn, nếu bạn có thể đưa ra câu trả lời ngắn gọn, tối đa.
eRaisedToX

12

Tôi chắc chắn rằng bạn có thể tìm thấy một danh sách rộng lớn về sự khác biệt bằng cách đơn giản là tìm kiếm thứ gì đó như 'Android IntentService vs Service'

Một trong những khác biệt quan trọng hơn trên mỗi ví dụ là IntentService sẽ tự kết thúc sau khi hoàn thành.

Một số ví dụ (nhanh chóng tạo nên) có thể là;

IntentService: Nếu bạn muốn tải xuống một loạt các hình ảnh khi bắt đầu mở ứng dụng của bạn. Đó là quy trình một lần và có thể tự dọn sạch sau khi mọi thứ được tải xuống.

Dịch vụ: Dịch vụ sẽ liên tục được sử dụng để liên lạc giữa ứng dụng của bạn và back-end với các lệnh gọi API web. Ngay cả khi nó đã hoàn thành với nhiệm vụ hiện tại của nó, bạn vẫn muốn nó xuất hiện sau đó vài phút, để liên lạc nhiều hơn.


2
Tôi đã không tìm thấy một ví dụ có thể được thực hiện với một và không phải với ví dụ khác. chỉ là một số giải thích mà không giúp tôi.
roiberg

1
Hãy thử trang web này, nó có rất nhiều lời giải thích tốt về các khái niệm cơ bản của Android với các ví dụ phong nha vogella.com/articles/AndroidService/article.html
Stefan de Bruijn

4
Một ví dụ khác về "cách sử dụng". không khi cụ thể sử dụng dịch vụ và khi intentservice. Vui lòng cho tôi một ví dụ lý thuyết và không liên kết đến "cách sử dụng" hoặc bất kỳ ý thích nào khác cho metter đó. Tôi không yêu cầu bạn "làm việc" cho tôi trong khi tôi không làm gì cả, chỉ là tôi đã thấy tất cả những điều đó và vẫn không chắc chắn.
roiberg

5
Đó là sự khác biệt khá quan trọng. ví dụ: nếu bạn sử dụng dịch vụ để duy trì kết nối liên tục với máy chủ, bạn không thể sử dụng dịch vụ nội bộ vì nó đã chấm dứt ngay sau khi hoàn thành tất cả các nhiệm vụ của mình
pelotasplus 20/03/13

24
Khi tôi google nó, nó mang tôi đến đây. bây giờ tôi đang ở trong một vòng lặp vô hạn.
Lou Morda

12

Dịch vụ ý định

IntentServicechạy trên chủ đề riêng của nó. Nó sẽ tự dừng lại khi nó hoàn thành. Giống như lửa và quên đi. Các cuộc gọi tiếp theo sẽ được xếp hàng. Tốt cho hàng đợi cuộc gọi. Bạn cũng có thể quay nhiều chủ đề trong IntentServicenếu bạn cần- Bạn có thể đạt được điều này bằng cách sử dụng ThreadPoolExecutor. Tôi nói điều này bởi vì nhiều người hỏi tôi "tại sao sử dụng IntentServicevì nó không hỗ trợ thực thi song song". IntentServicechỉ là một chủ đề. Bạn có thể làm bất cứ điều gì bạn cần bên trong nó - Thậm chí quay nhiều luồng. Nhắc nhở duy nhất là IntentServicekết thúc ngay khi bạn quay nhiều chủ đề đó. Nó không chờ đợi những chủ đề trở lại. Bạn cần phải chăm sóc điều này. Vì vậy, tôi khuyên bạn nên sử dụng ThreadPoolExecutortrong các kịch bản.

  • Tốt cho đồng bộ hóa, tải lên vv.

Dịch vụ

Theo mặc định Servicechạy trên chủ đề chính. Bạn cần phải quay một chủ đề công nhân để làm công việc của bạn. Bạn cần dừng lại servicemột cách rõ ràng. Tôi đã sử dụng nó cho một tình huống khi bạn cần chạy các công cụ trong nền ngay cả khi bạn rời khỏi ứng dụng của mình và quay lại nhiều hơn cho Headless service.

  • Một lần nữa bạn có thể chạy nhiều chủ đề nếu bạn cần.
  • Có thể được sử dụng cho các ứng dụng như máy nghe nhạc.

Bạn luôn có thể liên lạc trở lại hoạt động của mình bằng cách sử dụng BroadcastReceiversnếu bạn cần.


8

IntentService là một phần mở rộng của Dịch vụ được tạo ra để dễ dàng thực thi một tác vụ cần được thực thi trong nền và trong một luồng riêng biệt.

IntentService bắt đầu, tạo một luồng và chạy nhiệm vụ của nó trong luồng. Sau khi thực hiện, nó làm sạch mọi thứ. Chỉ một phiên bản của IntentService có thể chạy cùng một lúc, một số cuộc gọi được thực hiện.

Nó rất đơn giản để sử dụng và rất thuận tiện cho nhiều mục đích sử dụng, ví dụ như tải xuống công cụ. Nhưng nó có những hạn chế có thể khiến bạn muốn sử dụng thay vì Dịch vụ cơ bản (không đơn giản).

Ví dụ: một dịch vụ được kết nối với máy chủ xmpp và bị ràng buộc bởi các hoạt động có thể được thực hiện đơn giản bằng cách sử dụng IntentService. Cuối cùng, bạn sẽ bỏ qua hoặc ghi đè lên nội dung của IntentService.


có vẻ như hầu hết những người muốn chạy một dịch vụ chạy dài thực sự trong nền cuối cùng đều cố gắng tìm kiếm về IntentService vì các tài liệu làm cho nó có vẻ như là để làm điều đó, nhưng bạn hầu như cũng có thể sử dụng Thread mới (Runnable mới ()). start (). nói cách khác, khi nói về "sinh ra một luồng mới", đó là tất cả những gì nó làm, nó không chuyển nó sang một quy trình riêng mà thực sự là điều mà hầu hết mọi người mong muốn làm khi họ muốn tách một số mã đang chạy ra khỏi Hoạt động ! (bởi vì chỉ sinh ra các chủ đề là một lót dù sao)
Lassi Kinnunen

dịch vụ aimService cũng đảm nhiệm vòng đời của luồng và sử dụng bộ xử lý, giúp trình lập lịch biểu. Nó cũng đảm bảo chỉ có một phiên bản đang chạy và xếp hàng các cuộc gọi khác.
njzk2

5

Nếu ai đó có thể chỉ cho tôi một ví dụ về một cái gì đó mà bạn có thể được thực hiện với một IntentServicevà không thể được thực hiện bằng servicecách khác.

IntentService không thể được sử dụng cho Nghe lâu, Giống như cho Trình nghe XMPP, một toán tử thời gian duy nhất, thực hiện công việc và tạm biệt sóng.

Ngoài ra, nó chỉ có một threadworker, nhưng với một mẹo, bạn có thể sử dụng nó như không giới hạn.


4

Sự khác biệt chính giữa a ServiceIntentService được mô tả như sau:

Dịch vụ :

1.A Service theo mặc định, chạy trên luồng chính của ứng dụng. (Ở đây không có luồng xử lý mặc định nào khả dụng). Vì vậy, người dùng cần tạo một luồng riêng và thực hiện công việc cần thiết trong luồng đó.

2. Cho phép nhiều yêu cầu cùng một lúc. (Đa luồng)

Dịch vụ ý định:

1.Bây giờ, đến IntentServiceđây, ở đây một luồng công nhân mặc định có sẵn để thực hiện bất kỳ hoạt động nào. Lưu ý rằng - Bạn cần thực hiệnonHandleIntent() phương thức, phương thức nhận ý định cho mỗi yêu cầu bắt đầu, nơi bạn có thể thực hiện công việc nền.

2.Nhưng nó chỉ cho phép một yêu cầu tại một thời điểm.


3

Android IntentService vs Dịch vụ

1. Dịch vụ

  • Một dịch vụ được gọi bằng startService ().
  • Một dịch vụ có thể được gọi từ bất kỳ chủ đề.
  • Một Dịch vụ chạy các hoạt động nền trên Chủ đề chính của Ứng dụng theo mặc định. Do đó, nó có thể chặn giao diện người dùng ứng dụng của bạn.
  • Một dịch vụ được gọi nhiều lần sẽ tạo ra nhiều trường hợp.
  • Một dịch vụ cần được dừng lại bằng stopSelf () hoặc stopService ().
  • Dịch vụ Android có thể chạy các hoạt động song song.

2. Dịch vụ ý định

  • Một IntentService được gọi bằng Intent.
  • Một IntentService chỉ có thể được gọi từ luồng chính.
  • IntentService tạo một luồng công nhân riêng biệt để chạy các hoạt động nền.
  • Một IntentService được gọi nhiều lần sẽ không tạo ra nhiều phiên bản.
  • Một IntentService tự động dừng sau khi hoàn thành hàng đợi. Không cần kích hoạt stopService () hoặc stopSelf ().
  • Trong IntentService, nhiều cuộc gọi có mục đích được tự động xếp hàng và chúng sẽ được thực hiện tuần tự.
  • IntentService không thể chạy hoạt động song song như Dịch vụ.

Tham khảo từ đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.