AndroidDebugBridge
public
class
AndroidDebugBridge
extends Object
| java.lang.Object | |
| ↳ | com.android.tradefed.device.server.AndroidDebugBridge |
Kết nối với cầu gỡ lỗi Android (adb) phía máy chủ
Đây là điểm trung tâm để giao tiếp với mọi thiết bị, trình mô phỏng hoặc ứng dụng đang chạy trên các thiết bị đó.
Bạn phải gọi init(boolean) trước khi thực hiện bất kỳ thao tác nào.
Tóm tắt
Lớp lồng ghép | |
|---|---|
interface |
AndroidDebugBridge.IClientChangeListener
Các lớp triển khai giao diện này cung cấp các phương thức xử lý các thay đổi về |
interface |
AndroidDebugBridge.IDebugBridgeChangeListener
Các lớp triển khai giao diện này cung cấp một phương thức xử lý các thay đổi về |
interface |
AndroidDebugBridge.IDeviceChangeListener
Các lớp triển khai giao diện này cung cấp các phương thức xử lý việc thêm, xoá và thay đổi |
Hằng số | |
|---|---|
int |
DEFAULT_START_ADB_TIMEOUT_MILLIS
Thời gian chờ mặc định được dùng khi khởi động máy chủ ADB |
Trường | |
|---|---|
public
static
final
AdbVersion |
MIN_ADB_VERSION
Phiên bản tối thiểu và tối đa của adb được hỗ trợ. |
Phương thức công khai | |
|---|---|
static
void
|
addClientChangeListener(AndroidDebugBridge.IClientChangeListener listener)
Thêm trình nghe vào tập hợp trình nghe sẽ nhận được thông báo khi một thuộc tính |
static
void
|
addDebugBridgeChangeListener(AndroidDebugBridge.IDebugBridgeChangeListener listener)
Thêm trình nghe vào tập hợp trình nghe sẽ được thông báo khi một |
static
void
|
addDeviceChangeListener(AndroidDebugBridge.IDeviceChangeListener listener)
Thêm trình nghe vào tập hợp trình nghe sẽ được thông báo khi |
static
void
|
clientChanged(ClientImpl client, int changeMask)
Thông báo cho trình nghe về |
static
AndroidDebugBridge
|
createBridge(long timeout, TimeUnit unit)
Tạo một |
static
AndroidDebugBridge
|
createBridge(String osLocation, boolean forceNewBridge)
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Hãy chuyển sang sử dụng |
static
AndroidDebugBridge
|
createBridge()
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Hãy chuyển sang sử dụng |
static
AndroidDebugBridge
|
createBridge(String osLocation, boolean forceNewBridge, long timeout, TimeUnit unit)
Tạo một cầu gỡ lỗi mới từ vị trí của công cụ dòng lệnh. |
static
void
|
deviceChanged(IDevice device, int changeMask)
Thông báo cho trình nghe về |
static
void
|
deviceConnected(IDevice device)
Thông báo cho trình nghe về |
static
void
|
deviceDisconnected(IDevice device)
Thông báo cho trình nghe về |
static
void
|
disableFakeAdbServerMode()
|
static
void
|
disconnectBridge()
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Hãy chuyển sang sử dụng |
static
boolean
|
disconnectBridge(long timeout, TimeUnit unit)
Ngắt kết nối cầu gỡ lỗi hiện tại và huỷ đối tượng. |
static
void
|
enableFakeAdbServerMode(int port)
|
static
ListenableFuture<AdbVersion>
|
getAdbVersion(File adb)
|
static
AndroidDebugBridge
|
getBridge()
Trả về cầu gỡ lỗi hiện tại. |
static
boolean
|
getClientSupport()
Trả về liệu ddmlib có được thiết lập để hỗ trợ việc giám sát và tương tác với |
int
|
getConnectionAttemptCount()
Trả về số lần đối tượng |
static
int
|
getDebugBridgeChangeListenerCount()
|
static
int
|
getDeviceChangeListenerCount()
|
IDevice[]
|
getDevices()
Trả lại thiết bị. |
ListenableFuture<
|
getRawDeviceList()
Trả về tập hợp các thiết bị do dòng lệnh adb báo cáo. |
int
|
getRestartAttemptCount()
Trả về số lần đối tượng |
static
InetSocketAddress
|
getSocketAddress()
Phương thức này không được dùng nữa.
Phương thức này trả về một địa chỉ máy chủ vòng lặp có thể không khớp với địa chỉ mà máy chủ ADB sử dụng. Tức là JVM có thể ở chế độ IPv4 trong khi máy chủ ADB được lưu trữ trên địa chỉ vòng lặp IPv6. Ưu tiên |
static
ListenableFuture<String>
|
getVirtualDeviceId(ListeningExecutorService service, File adb, IDevice device)
|
boolean
|
hasInitialDeviceList()
Trả về việc cầu nối đã lấy danh sách ban đầu từ adb sau khi được tạo hay chưa. |
static
void
|
init(AdbInitOptions options)
Tương tự như |
static
void
|
init(boolean clientSupport)
Khởi chạy thư viện |
static
void
|
init(boolean clientSupport, boolean useLibusb,
Tương tự như |
static
void
|
initIfNeeded(boolean clientSupport)
Chỉ khởi chạy thư viện nếu cần; không dùng nữa cho các mục đích sử dụng không phải kiểm thử. |
boolean
|
isConnected()
Trả về xem đối tượng |
static
boolean
|
isUserManagedAdbMode()
|
static
SocketChannel
|
openConnection()
Cố gắng kết nối với máy chủ cầu gỡ lỗi Android cục bộ. |
static
void
|
removeClientChangeListener(AndroidDebugBridge.IClientChangeListener listener)
Xoá trình nghe khỏi tập hợp trình nghe sẽ nhận được thông báo khi một thuộc tính |
static
void
|
removeDebugBridgeChangeListener(AndroidDebugBridge.IDebugBridgeChangeListener listener)
Xoá trình nghe khỏi tập hợp trình nghe sẽ được thông báo khi một |
static
void
|
removeDeviceChangeListener(AndroidDebugBridge.IDeviceChangeListener listener)
Xoá trình nghe khỏi tập hợp trình nghe sẽ nhận được thông báo khi |
boolean
|
restart(long timeout, TimeUnit unit)
Khởi động lại adb nhưng không khởi động lại các dịch vụ xung quanh. |
boolean
|
restart()
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Hãy chuyển sang sử dụng |
boolean
|
startAdb(long timeout, TimeUnit unit)
Khởi động máy chủ phía máy chủ lưu trữ adb. |
static
void
|
terminate()
Chấm dứt thư viện ddm. |
Hằng số
DEFAULT_START_ADB_TIMEOUT_MILLIS
public static final int DEFAULT_START_ADB_TIMEOUT_MILLIS
Thời gian chờ mặc định được dùng khi khởi động máy chủ ADB
Giá trị hằng số: 20000 (0x00004e20)
Trường
MIN_ADB_VERSION
public static final AdbVersion MIN_ADB_VERSION
Phiên bản tối thiểu và tối đa của adb được hỗ trợ. Điều này tương ứng với ADB_SERVER_VERSION có trong //device/tools/adb/adb.h
Phương thức công khai
addClientChangeListener
public static void addClientChangeListener (AndroidDebugBridge.IClientChangeListener listener)
Thêm trình nghe vào tập hợp trình nghe sẽ nhận được thông báo khi một thuộc tính ClientImpl thay đổi, bằng cách gửi cho trình nghe một trong các thông báo được xác định trong giao diện IClientChangeListener.
| Tham số | |
|---|---|
listener |
AndroidDebugBridge.IClientChangeListener: Trình nghe cần được thông báo. |
addDebugBridgeChangeListener
public static void addDebugBridgeChangeListener (AndroidDebugBridge.IDebugBridgeChangeListener listener)
Thêm trình nghe vào tập hợp trình nghe sẽ được thông báo khi một AndroidDebugBridge mới được kết nối, bằng cách gửi một trong các thông báo được xác định trong giao diện IDebugBridgeChangeListener.
| Tham số | |
|---|---|
listener |
AndroidDebugBridge.IDebugBridgeChangeListener: Trình nghe cần được thông báo. |
addDeviceChangeListener
public static void addDeviceChangeListener (AndroidDebugBridge.IDeviceChangeListener listener)
Thêm trình nghe vào tập hợp trình nghe sẽ được thông báo khi IDevice được kết nối, ngắt kết nối hoặc khi các thuộc tính hoặc danh sách ClientImpl của thành phần này thay đổi, bằng cách gửi một trong các thông báo được xác định trong giao diện IDeviceChangeListener.
| Tham số | |
|---|---|
listener |
AndroidDebugBridge.IDeviceChangeListener: Trình nghe cần được thông báo. |
clientChanged
public static void clientChanged (ClientImpl client, int changeMask)
Thông báo cho trình nghe về ClientImpl đã được sửa đổi.
Thông báo cho các trình nghe được thực hiện trong một khối được đồng bộ hoá. Điều quan trọng là bạn phải dự kiến rằng người nghe có thể truy cập vào nhiều phương thức IDevice cũng như getDevices() sử dụng khoá nội bộ.
| Tham số | |
|---|---|
client |
ClientImpl: Client đã sửa đổi. |
changeMask |
int: mặt nạ cho biết những thay đổi trong Client |
createBridge
public static AndroidDebugBridge createBridge (long timeout, TimeUnit unit)
Tạo một AndroidDebugBridge không được liên kết với bất kỳ tệp thực thi cụ thể nào.
Cầu nối này sẽ yêu cầu adb đang chạy. Không thể bắt đầu/dừng/khởi động lại adb.
Nếu cầu đã được bắt đầu, thì cầu sẽ được trả về trực tiếp mà không có thay đổi nào (tương tự như khi gọi getBridge()).
| Tham số | |
|---|---|
timeout |
long |
unit |
TimeUnit |
| Giá trị trả về | |
|---|---|
AndroidDebugBridge |
một cầu nối đã kết nối hoặc giá trị rỗng nếu xảy ra lỗi trong khi tạo hoặc kết nối với cầu nối |
createBridge
public static AndroidDebugBridge createBridge (String osLocation, boolean forceNewBridge)
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Thay vào đó, hãy sử dụng createBridge(String, boolean, long, TimeUnit).
Tạo một cầu gỡ lỗi mới từ vị trí của công cụ dòng lệnh.
Mọi máy chủ hiện có sẽ bị ngắt kết nối, trừ phi vị trí giống nhau và
forceNewBridge được đặt thành false.
| Tham số | |
|---|---|
osLocation |
String: vị trí của công cụ dòng lệnh "adb" |
forceNewBridge |
boolean: buộc tạo một cầu nối mới ngay cả khi đã có một cầu nối có cùng vị trí. |
| Giá trị trả về | |
|---|---|
AndroidDebugBridge |
một cầu nối đã kết nối hoặc giá trị rỗng nếu xảy ra lỗi trong khi tạo hoặc kết nối với cầu nối |
createBridge
public static AndroidDebugBridge createBridge ()
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Thay vào đó, hãy sử dụng createBridge(long, TimeUnit).
Tạo một AndroidDebugBridge không được liên kết với bất kỳ tệp thực thi cụ thể nào.
Cầu nối này sẽ yêu cầu adb đang chạy. Không thể bắt đầu/dừng/khởi động lại adb.
Nếu cầu đã được bắt đầu, thì cầu sẽ được trả về trực tiếp mà không có thay đổi nào (tương tự như khi gọi getBridge()).
| Giá trị trả về | |
|---|---|
AndroidDebugBridge |
một cầu nối đã kết nối hoặc giá trị rỗng nếu xảy ra lỗi trong khi tạo hoặc kết nối với cầu nối |
createBridge
public static AndroidDebugBridge createBridge (String osLocation, boolean forceNewBridge, long timeout, TimeUnit unit)
Tạo một cầu gỡ lỗi mới từ vị trí của công cụ dòng lệnh.
Mọi máy chủ hiện có sẽ bị ngắt kết nối, trừ phi vị trí giống nhau và
forceNewBridge được đặt thành false.
| Tham số | |
|---|---|
osLocation |
String: vị trí của công cụ dòng lệnh "adb" |
forceNewBridge |
boolean: buộc tạo một cầu nối mới ngay cả khi đã có một cầu nối có cùng vị trí. |
timeout |
long: thời gian chờ tối đa |
unit |
TimeUnit: đơn vị thời gian của đối số timeout |
| Giá trị trả về | |
|---|---|
AndroidDebugBridge |
cầu nối đã kết nối hoặc giá trị rỗng nếu xảy ra lỗi trong khi tạo hoặc kết nối với cầu nối |
deviceChanged
public static void deviceChanged (IDevice device, int changeMask)
Thông báo cho trình nghe về IDevice đã được sửa đổi.
Thông báo cho các trình nghe được thực hiện trong một khối được đồng bộ hoá. Điều quan trọng là bạn phải dự kiến rằng người nghe có thể truy cập vào nhiều phương thức IDevice cũng như getDevices() sử dụng khoá nội bộ.
| Tham số | |
|---|---|
device |
IDevice: IDevice đã sửa đổi. |
changeMask |
int |
deviceConnected
public static void deviceConnected (IDevice device)
Thông báo cho trình nghe về IDevice mới.
Thông báo cho các trình nghe được thực hiện trong một khối được đồng bộ hoá. Điều quan trọng là bạn phải dự kiến rằng người nghe có thể truy cập vào nhiều phương thức IDevice cũng như getDevices() sử dụng khoá nội bộ.
| Tham số | |
|---|---|
device |
IDevice: IDevice mới. |
deviceDisconnected
public static void deviceDisconnected (IDevice device)
Thông báo cho trình nghe về IDevice bị ngắt kết nối.
Thông báo cho các trình nghe được thực hiện trong một khối được đồng bộ hoá. Điều quan trọng là bạn phải dự kiến rằng người nghe có thể truy cập vào nhiều phương thức IDevice cũng như getDevices() sử dụng khoá nội bộ.
| Tham số | |
|---|---|
device |
IDevice: IDevice đã ngắt kết nối. |
disableFakeAdbServerMode
public static void disableFakeAdbServerMode ()
disconnectBridge
public static void disconnectBridge ()
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Thay vào đó, hãy sử dụng disconnectBridge(long, TimeUnit).
Ngắt kết nối cầu gỡ lỗi hiện tại và huỷ đối tượng. Bạn sẽ phải tạo một đối tượng mới bằng createBridge(String, boolean).
Thao tác này cũng sẽ dừng máy chủ lưu trữ adb hiện tại.
disconnectBridge
public static boolean disconnectBridge (long timeout,
TimeUnit unit)Ngắt kết nối cầu gỡ lỗi hiện tại và huỷ đối tượng. Bạn sẽ phải tạo một đối tượng mới bằng createBridge(String, boolean).
Thao tác này cũng sẽ dừng máy chủ lưu trữ adb hiện tại.
| Tham số | |
|---|---|
timeout |
long |
unit |
TimeUnit |
| Giá trị trả về | |
|---|---|
boolean |
true nếu phương thức thành công trong thời gian chờ đã chỉ định. |
enableFakeAdbServerMode
public static void enableFakeAdbServerMode (int port)
| Tham số | |
|---|---|
port |
int |
getAdbVersion
public static ListenableFuture<AdbVersion> getAdbVersion (File adb)
| Tham số | |
|---|---|
adb |
File |
| Giá trị trả về | |
|---|---|
ListenableFuture<AdbVersion> |
|
getBridge
public static AndroidDebugBridge getBridge ()
Trả về cầu gỡ lỗi hiện tại. Có thể là null nếu không có tệp nào được tạo.
| Giá trị trả về | |
|---|---|
AndroidDebugBridge |
|
getClientSupport
public static boolean getClientSupport ()
Trả về liệu ddmlib có được thiết lập để hỗ trợ việc giám sát và tương tác với ClientImpl chạy trên IDevice hay không.
| Giá trị trả về | |
|---|---|
boolean |
|
getConnectionAttemptCount
public int getConnectionAttemptCount ()
Trả về số lần đối tượng AndroidDebugBridge đã cố gắng kết nối với trình nền adb.
| Giá trị trả về | |
|---|---|
int |
|
getDebugBridgeChangeListenerCount
public static int getDebugBridgeChangeListenerCount ()
| Giá trị trả về | |
|---|---|
int |
|
getDeviceChangeListenerCount
public static int getDeviceChangeListenerCount ()
| Giá trị trả về | |
|---|---|
int |
|
getRawDeviceList
public ListenableFuture<> getRawDeviceList ()
Trả về tập hợp các thiết bị do dòng lệnh adb báo cáo. Điều này chủ yếu dành cho Trợ lý kết nối hoặc các công cụ chẩn đoán khác cần xác thực trạng thái của danh sách getDevices() thông qua một kênh khác. Mã chỉ cần truy cập vào danh sách thiết bị nên gọi getDevices().
| Giá trị trả về | |
|---|---|
ListenableFuture< |
|
getRestartAttemptCount
public int getRestartAttemptCount ()
Trả về số lần đối tượng AndroidDebugBridge đã cố gắng khởi động lại trình nền adb.
| Giá trị trả về | |
|---|---|
int |
|
getSocketAddress
public static InetSocketAddress getSocketAddress ()
Phương thức này không được dùng nữa.
Phương thức này trả về một địa chỉ máy chủ vòng lặp có thể không khớp với địa chỉ mà máy chủ ADB sử dụng. Tức là JVM có thể ở chế độ IPv4 trong khi máy chủ ADB được lưu trữ trên địa chỉ vòng lặp IPv6. Ưu tiên openConnection() thay vì khi mở một kết nối đến máy chủ ADB.
Trả về địa chỉ ổ cắm của máy chủ ADB trên máy chủ lưu trữ.
Phương thức này sẽ cố gắng trả về một địa chỉ ổ cắm đã biết hoạt động bằng cách mở một kênh ổ cắm đến máy chủ ADB. Hệ thống sẽ thử cả địa chỉ vòng lặp IPv4 và IPv6. Trong trường hợp không có phương thức nào kết nối được, phương thức này sẽ quay lại việc trả về địa chỉ vòng lặp được JVM ưu tiên. Bạn cần có logic dự phòng này để ngăn API bị hỏng.
Nếu chế độ máy chủ ADB giả được bật, phương thức này sẽ tự động quay lại việc triển khai cũ mà không cố gắng kết nối với ADB.
| Giá trị trả về | |
|---|---|
InetSocketAddress |
|
getVirtualDeviceId
public static ListenableFuture<String> getVirtualDeviceId (ListeningExecutorService service,
File adb,
IDevice device)| Tham số | |
|---|---|
service |
ListeningExecutorService |
adb |
File |
device |
IDevice |
| Giá trị trả về | |
|---|---|
ListenableFuture<String> |
|
hasInitialDeviceList
public boolean hasInitialDeviceList ()
Trả về việc cầu nối đã lấy danh sách ban đầu từ adb sau khi được tạo hay chưa.
Việc gọi getDevices() ngay sau createBridge(String, boolean) thường sẽ dẫn đến một danh sách trống. Điều này là do cơ chế giao tiếp không đồng bộ nội bộ với adb không đảm bảo rằng danh sách IDevice đã được tạo trước khi gọi đến getDevices().
Cách được đề xuất để lấy danh sách đối tượng IDevice là tạo một đối tượng IDeviceChangeListener.
| Giá trị trả về | |
|---|---|
boolean |
|
init
public static void init (AdbInitOptions options)
Tương tự như init(boolean), có khả năng truyền một nhóm biến môi trường tuỳ chỉnh.
| Tham số | |
|---|---|
options |
AdbInitOptions |
init
public static void init (boolean clientSupport)
Khởi chạy thư viện ddm.
Bạn phải gọi phương thức này một lần trước khi gọi createBridge(String, boolean).
Các lựa chọn ưu tiên của ddmlib cũng phải được khởi chạy bằng bất kỳ giá trị mặc định nào đã thay đổi so với các giá trị mặc định.
Khi ứng dụng thoát, terminate() sẽ được gọi.
| Tham số | |
|---|---|
clientSupport |
boolean: Cho biết liệu thư viện có nên bật tính năng giám sát và tương tác với các ứng dụng đang chạy trên thiết bị hay không. |
init
public static void init (boolean clientSupport,
boolean useLibusb,
env) Tương tự như init(boolean), có khả năng bật libusb và truyền một nhóm biến môi trường tuỳ chỉnh.
| Tham số | |
|---|---|
clientSupport |
boolean |
useLibusb |
boolean |
env |
|
initIfNeeded
public static void initIfNeeded (boolean clientSupport)
Chỉ khởi chạy thư viện nếu cần; không dùng nữa cho các mục đích sử dụng không phải kiểm thử.
| Tham số | |
|---|---|
clientSupport |
boolean: Cho biết liệu thư viện có nên bật tính năng giám sát và tương tác với các ứng dụng đang chạy trên thiết bị hay không. |
Xem thêm:
isConnected
public boolean isConnected ()
Trả về xem đối tượng AndroidDebugBridge có còn kết nối với daemon adb hay không.
| Giá trị trả về | |
|---|---|
boolean |
|
isUserManagedAdbMode
public static boolean isUserManagedAdbMode ()
| Giá trị trả về | |
|---|---|
boolean |
Nếu hoạt động ở chế độ ADB do người dùng quản lý, trong đó ddmlib sẽ và không được quản lý máy chủ ADB. |
openConnection
public static SocketChannel openConnection ()
Cố gắng kết nối với máy chủ cầu gỡ lỗi Android cục bộ.
| Giá trị trả về | |
|---|---|
SocketChannel |
một ổ cắm đã kết nối nếu thành công |
| Gửi | |
|---|---|
|
sẽ xảy ra lỗi khi mở kết nối |
removeClientChangeListener
public static void removeClientChangeListener (AndroidDebugBridge.IClientChangeListener listener)
Xoá trình nghe khỏi tập hợp trình nghe sẽ nhận được thông báo khi một thuộc tính ClientImpl thay đổi.
| Tham số | |
|---|---|
listener |
AndroidDebugBridge.IClientChangeListener: Trình nghe không còn được thông báo nữa. |
removeDebugBridgeChangeListener
public static void removeDebugBridgeChangeListener (AndroidDebugBridge.IDebugBridgeChangeListener listener)
Xoá trình nghe khỏi tập hợp trình nghe sẽ được thông báo khi một AndroidDebugBridge mới bắt đầu.
| Tham số | |
|---|---|
listener |
AndroidDebugBridge.IDebugBridgeChangeListener: Trình nghe không còn được thông báo nữa. |
removeDeviceChangeListener
public static void removeDeviceChangeListener (AndroidDebugBridge.IDeviceChangeListener listener)
Xoá trình nghe khỏi tập hợp trình nghe sẽ được thông báo khi IDevice được kết nối, ngắt kết nối hoặc khi các thuộc tính của IDevice hoặc danh sách ClientImpl của IDevice thay đổi.
| Tham số | |
|---|---|
listener |
AndroidDebugBridge.IDeviceChangeListener: Trình nghe không còn được thông báo nữa. |
Khởi động lại
public boolean restart (long timeout,
TimeUnit unit)Khởi động lại adb nhưng không khởi động lại các dịch vụ xung quanh.
| Tham số | |
|---|---|
timeout |
long |
unit |
TimeUnit |
| Giá trị trả về | |
|---|---|
boolean |
true nếu thành công. |
Khởi động lại
public boolean restart ()
Phương thức này không được dùng nữa.
Phương thức này có thể bị treo nếu ADB không phản hồi. Thay vào đó, hãy sử dụng restart(long, TimeUnit).
Khởi động lại adb nhưng không khởi động lại các dịch vụ xung quanh.
| Giá trị trả về | |
|---|---|
boolean |
true nếu thành công. |
startAdb
public boolean startAdb (long timeout,
TimeUnit unit)Khởi động máy chủ phía máy chủ lưu trữ adb. Bạn không nên sử dụng phương thức này khi dùng máy chủ ADB do người dùng quản lý vì vòng đời của máy chủ phải do người dùng quản lý, chứ không phải ddmlib.
| Tham số | |
|---|---|
timeout |
long |
unit |
TimeUnit |
| Giá trị trả về | |
|---|---|
boolean |
true nếu thành công |
chấm dứt
public static void terminate ()
Chấm dứt thư viện ddm. Bạn phải gọi phương thức này khi ứng dụng kết thúc.