2010-05-05 45 views
5

Tôi đã sử dụng IntentService trong mã của tôi thay vì Dịch vụ vì IntentService tạo chuỗi cho tôi trong onHandleIntent (Intent intent), vì vậy tôi không phải tự tạo Thead trong mã dịch vụ của mình.Hành vi không mong muốn của IntentService

Tôi dự kiến ​​rằng hai ý định vào cùng IntentSerivce sẽ thực hiện song song vì một luồng được tạo trong IntentService cho mỗi phát minh. Nhưng mã của tôi bật ra rằng hai ý định được thực hiện theo cách tuần tự.

Đây là mã IntentService tôi:

public class UpdateService extends IntentService { 

    public static final String TAG = "HelloTestIntentService"; 

    public UpdateService() { 
     super("News UpdateService"); 
    } 

    protected void onHandleIntent(Intent intent) { 

     String userAction = intent 
     .getStringExtra("userAction"); 

     Log.v(TAG, "" + new Date() + ", In onHandleIntent for userAction = " + userAction + ", thread id = " + Thread.currentThread().getId()); 

     if ("1".equals(userAction)) { 
      try { 
       Thread.sleep(20 * 1000); 
      } catch (InterruptedException e) { 
       Log.e(TAG, "error", e); 
      } 

      Log.v(TAG, "" + new Date() + ", This thread is waked up."); 
     } 
    } 
} 

Và cuộc gọi mã dịch vụ là bên dưới:

public class HelloTest extends Activity { 

    //@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     Intent selectIntent = new Intent(this, UpdateService.class); 
     selectIntent.putExtra("userAction", 
       "1"); 

     this.startService(selectIntent); 

     selectIntent = new Intent(this, UpdateService.class); 
     selectIntent.putExtra("userAction", 
       "2"); 

     this.startService(selectIntent); 

    } 
} 

tôi thấy thông tin đăng nhập này trong nhật ký:

V/HelloTestIntentService( 848): Wed May 05 14:59:37 PDT 2010, In onHandleIntent for userAction = 1, thread id = 8 
D/dalvikvm( 609): GC freed 941 objects/55672 bytes in 99ms 
V/HelloTestIntentService( 848): Wed May 05 15:00:00 PDT 2010, This thread is waked up. 
V/HelloTestIntentService( 848): Wed May 05 15:00:00 PDT 2010, In onHandleIntent for userAction = 2, thread id = 8 
I/ActivityManager( 568): Stopping service: com.example.android/.UpdateService 

Các nhật ký cho thấy ý định thứ hai chờ ý định đầu tiên kết thúc và chúng nằm trong cùng một luồng.

Có bất kỳ điều gì tôi hiểu sai về IntentService. Để thực hiện hai mục đích dịch vụ thực thi song song, tôi có phải thay thế IntentService bằng dịch vụ và tự khởi chạy một luồng trong mã dịch vụ không?

Cảm ơn.

Trả lời

6

Theo như tôi biết, IntentService có một chuỗi xử lý và mỗi hàng đợi có chủ ý trong chuỗi đó. Khi tất cả ý định xếp hàng được thực hiện, dịch vụ sẽ thoát. Nó không tạo chủ đề độc lập cho mỗi mục đích. Tôi không biết bất kỳ lớp con Dịch vụ nào hoạt động theo cách bạn mô tả, có thể bạn sẽ phải viết cho riêng mình.

+3

Mẫu thiết kế của IntentService là hàng đợi công việc đảm bảo rằng các yêu cầu được xếp hàng đợi và không được xử lý song song. Như đã chỉ ra dưới đây, bạn có thể kích hoạt AsyncTask cho mỗi công việc song song. Hãy chắc chắn rằng mã dịch vụ của bạn là reentrant. – mobibob

9

Mục đích xếp hàng là toàn bộ điểm sử dụng IntentService.

1

Tôi nghĩ điều bạn muốn là AsyncTask thay vì Dịch vụ hoặc IntentService. Hoặc bạn luôn có thể bắn từ hông bằng cách xác định một runnable như thế này:

Runnable runnable = new Runnable() { 

    public void run() { 
     .... 
    } 
}; 
new Thread(runnable).start(); 

... cho mỗi tác vụ của bạn. Thành thật mà nói, điều đó có thể dễ dàng hơn so với việc xử lý các lớp trợ giúp Android này.

+0

Tôi sẽ sử dụng AsyncTask trên Runnable - chắc chắn sẽ giúp xử lý trước/sau và nhận lại kết quả cho chuỗi giao diện người dùng. Nếu bất cứ điều gì có thể kéo dài hơn tuổi thọ của hoạt động, thì sử dụng IntentService là cách để đi. – DustinB

+0

AsyncTask tốt, nhưng nên được sử dụng trong Dịch vụ, bạn nên luôn ghi nhớ vòng đời Android: các hoạt động bị hủy và tái tạo trong khi thay đổi cấu hình ... AsyncTask sẽ tham chiếu đến Hoạt động và có thể bị hủy ... –

7

Mọi yêu cầu đến IntentService được xử lý trên một chuỗi công nhân duy nhất và chỉ một yêu cầu sẽ được xử lý tại một thời điểm. Nếu bạn muốn thực hiện hai tác vụ song song, tôi nghĩ bạn cần sử dụng Dịch vụ và tạo chuỗi cho từng tác vụ sau khi Dịch vụ bắt đầu.

Đối với AsyncTask, có một nhóm chủ đề để xử lý tất cả các tác vụ. Nếu số nhiệm vụ của bạn vượt quá kích thước nhóm của luồng, một số trong số các AsyncTask này sẽ cần phải chờ cho đến khi một chuỗi từ nhóm trở nên khả dụng. Tuy nhiên, kích thước nhóm luồng thay đổi trong các phiên bản nền tảng khác nhau.

Dưới đây là kết quả thử nghiệm của tôi:

  • Android 2.2: kích thước hồ bơi thread = 5
  • Android 1.5: kích thước hồ bơi thread = 1
+0

Cảm ơn lời giải thích ngắn gọn. thực sự giúp – bschandramohan

Các vấn đề liên quan