This page is READ-ONLY. It is generated from the old site.
All timestamps are relative to 2013 (when this page is generated).
If you are looking for TeX support, please go to VietTUG.org

Starting service when user launches application

Does Service terminate slowly in Android OS?
Added by bronzeboyvn 11 months ago

Có nhiều tài liệu hướng dẫn sử dụng Service như một thread (hoặc process riêng biệt) chạy background, họ toàn hướng dẫn khởi tạo Service khi thiết bị boot xong. Mình có nhu cầu chạy một Service thực thi C++ binary process, C++ binary process chạy suốt dù ứng dụng chạy background hay foreground. Và khi người sử dụng nhấn "Quit", Service giết C++ binary process và ứng dụng hủy Service rồi kết thúc.
Mình cần khởi tạo Service khi người sử dụng bật ứng dụng và hủy Service khi người dùng "quit". Và đây là cách giải quyết:

 1 public class MyService extends Service {
 2     private final IBinder mBinder = new MyBinder();
 3     private boolean single;
 4 
 5     @Override
 6     public IBinder onBind(Intent arg0) {
 7         return mBinder;
 8     }
 9 
10     @Override
11     public void onCreate() {
12         super.onCreate();
13         single = true;
14         // do something
15     }
16 
17     @Override
18     public void onDestroy() {
19         super.onDestroy();
20         single = false;
21         // kill C++ binary process and release resource
22     }
23 
24     public class MyBinder extends Binder {
25         public MyService getService() {
26             return MyService.this;
27         }
28     }
29 
30     // các public methods khác được khai báo tiếp theo
31     // , để Application hoặc Activity gắn kết với service có thể gọi.
32     public void execute_cpp_binary() {
33         if (single) {
34             single = false;
35             // execute C++ binary in child process only one time
36         }
37     }
38 }

Application khởi tạo Service tại phương thức onCreate() (như vậy Service được khởi tạo khi người dùng bật ứng dụng).

1 public class MyApplication extends Application {
2     @Override
3     public void onCreate() {
4         super.onCreate();
5         startService(new Intent(getApplicationContext(),
6                 MyService.class));
7     }
8 }

Activity gắn kết với Service tại phương thức onCreate() và giải phóng Service tại phương thức onDestroy()

 1 public class MyActivity extends Activity {
 2     private ServiceConnection mConnection = new MyServiceConnection();
 3     private MyService myserv;
 4 
 5     @Override
 6     public void onCreate() {
 7         super.onCreate();
 8         bindService(new Intent(this, MyService.class), mConnection,
 9                 Context.BIND_AUTO_CREATE);
10         // do something
11     }
12 
13     @Override
14     public void onDestroy() {
15         super.onDestroy();
16         unbindService(mConnection);
17         // release resource
18     }
19 
20     // gọi phương thức này khi user nhất "Quit" 
21     private void stopService() {
22         MyApplication myapp = (MyApplication) getApplication();
23         myapp.stopService(new Intent(getApplicationContext(),
24                 MyService.class));
25         finish();
26     }
27 
28     private class MyServiceConnection extends ServiceConnection {
29         @Override
30         public void onServiceConnected(ComponentName className, IBinder binder) {
31             myserv = ((MyService.MyBinder) binder).getService();
32             myserv.execute_cpp_binary();
33         }
34         @Override
35         public void onServiceDisconnected(ComponentName className) {
36             myserv = null;
37         }
38     }
39 }

Trước khi biết sử dụng Service, ứng dụng chỉ thực thi C++ binary khi nó chạy foreground, khi ứng dụng chạy background mình giết C++ binary process trong phương thức onDestroy của Activity. Vì trong Android OS, ta không thể biết process của ứng dụng khi nào bị giết. Nếu không giết C++ binary process, một khi ứng dụng bị giết, C++ binary process trở thành zoombie, con của process 1 (init process). Chỉ khi restart thiết bị zoombie mới được Android OS thu dọn. Với cách hiện thực như vậy, ứng dụng hoàn tòan vô dụng khi chạy background. Service đã giúp ứng dụng quản lý C++ process:

 C++ binary process vẫn chạy khi ứng dụng chạy background.
 Giết C++ binary process khi cần thiết.

Tuy nhiên mình gặp một lỗi là sau khi "Quit" ứng dụng, nếu người sử dụng bật lại ứng dụng ngay thì ứng dụng sẽ bi treo và bị force close. Trong khi nếu chờ khỏang 10, 20 giây sau để bật lại ứng dụng, thì mọi thứ hòan tòan bình thường.

Android OS dọn dẹp Service quá chậm chạp hay là cách giải quyết của mình có vấn đề?
Android OS dọn dẹp Service nhanh. Lỗi ở chỗ mình gây deadlock tại phương thức OnDestroy của Service.


Comments