page.title=Bản kê khai Ứng dụng @jd:body
Mọi ứng dụng đều phải có một tệp AndroidManifest.xml (chính xác là tên gọi này) trong thư mục gốc của mình. Tệp bản kê khai trình bày những thông tin thiết yếu về ứng dụng của bạn với hệ thống Android, thông tin mà hệ thống phải có trước khi có thể chạy bất kỳ mã nào của ứng dụng. Ngoài một số mục đích khác, bản kê khai thực hiện những điều sau:
Sơ đồ bên dưới minh họa cấu trúc chung của tệp bản kê khai và mọi phần tử mà nó có thể chứa. Từng phần tử, cùng với tất cả thuộc tính của mình, sẽ được lập tài liệu theo dõi đầy đủ vào một tệp riêng. Để xem thông tin chi tiết về mọi phần tử, hãy nhấp vào tên phần tử trong sơ đồ, trong danh sách các phần tử theo thứ tự chữ cái mà tuân theo sơ đồ, hoặc trên bất kỳ nội dung nào khác đề cập tới tên phần tử.
<?xml version="1.0" encoding="utf-8"?> <manifest> <uses-permission /> <permission /> <permission-tree /> <permission-group /> <instrumentation /> <uses-sdk /> <uses-configuration /> <uses-feature /> <supports-screens /> <compatible-screens /> <supports-gl-texture /> <application> <activity> <intent-filter> <action /> <category /> <data /> </intent-filter> <meta-data /> </activity> <activity-alias> <intent-filter> . . . </intent-filter> <meta-data /> </activity-alias> <service> <intent-filter> . . . </intent-filter> <meta-data/> </service> <receiver> <intent-filter> . . . </intent-filter> <meta-data /> </receiver> <provider> <grant-uri-permission /> <meta-data /> <path-permission /> </provider> <uses-library /> </application> </manifest>
Tất cả phần tử có thể xuất hiện trong tệp bản kê khai được liệt kê ở bên dưới theo thứ tự chữ cái. Đây là những phần tử hợp pháp duy nhất; bạn không thể thêm các phần tử hay thuộc tính của chính mình.
<action>
<activity>
<activity-alias>
<application>
<category>
<data>
<grant-uri-permission>
<instrumentation>
<intent-filter>
<manifest>
<meta-data>
<permission>
<permission-group>
<permission-tree>
<provider>
<receiver>
<service>
<supports-screens>
<uses-configuration>
<uses-feature>
<uses-library>
<uses-permission>
<uses-sdk>
Một số quy ước và quy tắc áp dụng chung cho tất cả các phần tử và thuộc tính trong bản kê khai:
<manifest>
và
<application>
là bắt buộc phải có, chúng đều phải có mặt và chỉ có thể xảy ra một lần.
Hầu hết các phần tử khác có thể xảy ra nhiều lần hoặc không xảy ra — mặc dù ít
nhất một vài trong số chúng phải có mặt để bản kê khai thực sự có
ý nghĩa nào đó.
Nếu một phần tử chứa bất kỳ nội dung nào, nó có thể chứa các phần tử khác. Tất cả giá trị sẽ được đặt thông qua thuộc tính, chứ không phải là dữ liệu ký tự trong một phần tử.
Các phần tử cùng cấp thường không theo thứ tự. Ví dụ, các phần tử
<activity>
,
<provider>
, và
<service>
có thể được trộn lẫn với nhau theo bất kỳ trình tự nào. (Phần tử
<activity-alias>
là trường hợp ngoại lệ đối với quy tắc này: Nó phải tuân theo
<activity>
, đối tượng mà nó là bí danh cho.)
Ngoài một số thuộc tính của phần tử
<manifest>
gốc, tất cả tên thuộc tính đều bắt đầu bằng một tiền tố {@code android:}—
ví dụ, {@code android:alwaysRetainTaskState}. Do tiền tố này
phổ dụng, tài liệu thường bỏ sót nó khi tham chiếu tới các thuộc tính
theo tên.
<application>
) và các thành phần chính của nó — hoạt động
(<activity>
),
dịch vụ
(<service>
),
hàm nhận quảng bá
(<receiver>
),
và trình cung cấp nội dung
(<provider>
).
Nếu bạn định nghĩa một lớp con như vẫn luôn làm đối với lớp thành phần ({@link android.app.Activity}, {@link android.app.Service}, {@link android.content.BroadcastReceiver}, và {@link android.content.ContentProvider}), lớp con sẽ được khai báo thông qua một thuộc tính {@code name}. Tên phải bao gồm chỉ định gói đầy đủ. Ví dụ, một lớp con {@link android.app.Service} có thể được khai báo như sau:
<manifest . . . > <application . . . > <service android:name="com.example.project.SecretService" . . . > . . . </service> . . . </application> </manifest>
Tuy nhiên, do cách viết tốc ký, nếu ký tự đầu tiên của xâu là một dấu chấm,
xâu sẽ được nối với tên gói của ứng dụng (như được quy định bởi
thuộc tính của phần tử <manifest>
, package
). Cách gán sau cũng giống như trên:
<manifest package="com.example.project" . . . > <application . . . > <service android:name=".SecretService" . . . > . . . </service> . . . </application> </manifest>
Khi khởi động một thành phần, Android sẽ tạo một thực thể của lớp con được nêu tên. Nếu lớp con không được quy định, nó sẽ tạo một thực thể của lớp cơ sở.
<intent-filter . . . > <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.INSERT" /> <action android:name="android.intent.action.DELETE" /> . . . </intent-filter>
{@code @[gói:]kiểu:tên}
trong đó gói có thể được bỏ qua nếu tài nguyên nằm trong cùng gói với ứng dụng, kiểu là kiểu của tài nguyên — chẳng hạn như "xâu" hoặc — "vẽ được" và tên là tên nhận biết tài nguyên cụ thể. Ví dụ:
<activity android:icon="@drawable/smallPic" . . . >
Các giá trị từ một chủ đề được biểu diễn theo cách tương tự, nhưng với một '{@code ?}' thay vì '{@code @}' ở đầu:
{@code ?[gói:]kiểu:tên}
Phần sau đây mô tả cách phản ánh một số tính năng của Android trong tệp bản kê khai.
Các thành phần cốt lõi của một ứng dụng (hoạt động, dịch vụ và hàm nhận quảng bá) được kích hoạt bởi ý định. Ý định là một gói thông tin (một đối tượng {@link android.content.Intent}) mô tả một hành động mong muốn — bao gồm dữ liệu sẽ được dựa trên, thể loại của thành phần mà sẽ thực hiện hành động, và các chỉ dẫn thích hợp khác. Android định vị một thành phần phù hợp để hồi đáp ý định, khởi chạy một thực thể mới của thành phần nếu cần, và chuyển cho nó đối tượng đó Ý định.
Các thành phần sẽ quảng cáo khả năng của mình — các kiểu ý định mà chúng có thể
hồi đáp — thông qua các bộ lọc ý định. Do hệ thống Android phải
tìm hiểu một thành phần có thể xử lý những ý định nào trước khi khởi chạy thành phần đó,
bộ lọc ý định được quy định trong bản kê khai như là các phần tử
<intent-filter>
. Một thành phần có thể có nhiều bộ lọc, mỗi bộ lọc lại mô tả
một khả năng khác nhau.
Một ý định mà công khai nêu tên một thành phần mục tiêu sẽ kích hoạt thành phần đó; bộ lọc không có vai trò gì ở đây. Nhưng một ý định mà không quy định một mục tiêu theo tên sẽ chỉ có thể kích hoạt thành phần nếu nó có thể chuyển qua một trong các bộ lọc của thành phần.
Để biết thông tin về cách các đối tượng Ý định được kiểm tra thông qua bộ lọc ý định, hãy xem tài liệu riêng có tiêu đề Ý định và Bộ lọc Ý định.
Nhiều phần tử có thuộc tính {@code icon} và {@code label} cho một
biểu tượng nhỏ và nhãn văn bản mà có thể được hiển thị với người dùng. Một số cũng có thuộc tính
{@code description} cho văn bản giải trình dài hơn mà cũng có thể
được hiển thị trên màn hình. Ví dụ, phần tử
<permission>
có cả ba thuộc tính này, vì thế khi người dùng được hỏi xem có
cấp quyền cho một ứng dụng yêu cầu hay không, biểu tượng thể hiện
quyền, tên của quyền, và mô tả nội dung
của quyền đó đều có thể được trình bày cho người dùng xem.
Trong mọi trường hợp, biểu tượng và nhãn được đặt trong một phần tử chứa sẽ trở thành các thiết đặt
{@code icon} và {@code label} mặc định cho tất cả phần tử con của bộ chứa đó.
Vì thế, biểu tượng và nhãn được đặt trong phần tử
<application>
là biểu tượng và nhãn mặc định cho từng thành phần của ứng dụng.
Tương tự, biểu tượng và nhãn được đặt cho một thành phần — ví dụ, một phần tử
<activity>
— sẽ là các cài đặt mặc định cho từng phần tử
<intent-filter>
của thành phần đó. Nếu một phần tử
<application>
thiết đặt một nhãn, nhưng hoạt động và bộ lọc ý định của nó thì không,
nhãn ứng dụng sẽ được coi là nhãn của cả hoạt động và
bộ lọc ý định.
Biểu tượng và nhãn được đặt cho một bộ lọc ý định sẽ được sử dụng để biểu diễn một thành phần bất cứ khi nào thành phần đó được trình bày với người dùng để thực hiện chức năng mà bộ lọc đã quảng cáo. Ví dụ, một bộ lọc với các thiết đặt "{@code android.intent.action.MAIN}" và "{@code android.intent.category.LAUNCHER}" quảng cáo một hoạt động là hoạt động khởi đầu một ứng dụng — cụ thể, là hoạt động sẽ được hiển thị trong trình khởi chạy ứng dụng. Vì thế, biểu tượng và nhãn được đặt trong bộ lọc là những nội dung được hiển thị trong trình khởi chạy.
Một quyền là sự hạn chế giới hạn truy cập vào một phần của mã hoặc vào dữ liệu trên thiết bị. Giới hạn này được áp đặt nhằm bảo vệ dữ liệu và mã trọng yếu, có thể bị lạm dụng để bóp méo hoặc làm hỏng trải nghiệm người dùng.
Mỗi quyền được nhận biết bằng một nhãn duy nhất. Thông thường, nhãn cho biết hành động bị hạn chế. Ví dụ, sau đây là một số quyền được định nghĩa bởi Android:
{@code android.permission.CALL_EMERGENCY_NUMBERS}
{@code android.permission.READ_OWNER_DATA}
{@code android.permission.SET_WALLPAPER}
{@code android.permission.DEVICE_POWER}
Một tính năng có thể được bảo vệ bởi nhiều nhất một quyền.
Nếu một ứng dụng cần truy cập vào một tính năng được bảo vệ bởi một quyền,
nó phải khai báo rằng nó yêu cầu quyền đó cùng với một phần tử
<uses-permission>
trong bản kê khai. Lúc đó, khi ứng dụng được cài đặt trên
thiết bị, trình cài đặt sẽ xác định xem có cấp quyền
được yêu cầu hay không bằng cách kiểm tra các thẩm quyền đã ký chứng chỉ
của ứng dụng và trong một số trường hợp, bằng cách hỏi người dùng.
Nếu quyền được cấp, ứng dụng có thể sử dụng các tính năng
được bảo vệ. Nếu không, việc thử truy cập những tính năng đó sẽ thất bại
mà không có bất kỳ thông báo nào cho người dùng.
Một ứng dụng cũng có thể bảo vệ các thành phần của chính nó (hoạt động, dịch vụ,
hàm nhận quảng bá và trình cung cấp nội dung) bằng các quyền. Nó có thể sử dụng
bất kỳ quyền nào được định nghĩa bởi Android (được liệt kê trong
{@link android.Manifest.permission android.Manifest.permission}) hoặc được khai báo
bởi các ứng dụng khác. Hoặc nó có thể tự định nghĩa quyền của mình. Một quyền mới được khai báo
bằng phần tử
<permission>
. Ví dụ, một hoạt động có thể được bảo vệ như sau:
<manifest . . . > <permission android:name="com.example.project.DEBIT_ACCT" . . . /> <uses-permission android:name="com.example.project.DEBIT_ACCT" /> . . . <application . . .> <activity android:name="com.example.project.FreneticActivity" android:permission="com.example.project.DEBIT_ACCT" . . . > . . . </activity> </application> </manifest>
Lưu ý rằng trong ví dụ này, quyền {@code DEBIT_ACCT} không chỉ
được khai báo bằng phần tử
<permission>
, việc sử dụng quyền cũng được yêu cầu bằng phần tử
<uses-permission>
. Phải yêu cầu sử dụng quyền để các thành phần khác của
ứng dụng nhằm khởi chạy hoạt động được bảo vệ, mặc dù việc bảo vệ
do chính ứng dụng áp đặt.
Trong cùng ví dụ này, nếu thuộc tính {@code permission} được đặt thành một quyền
được khai báo ở nơi khác
(chẳng hạn như {@code android.permission.CALL_EMERGENCY_NUMBERS}, sẽ không
cần phải khai báo lại nó bằng một phần tử
<permission>
. Tuy nhiên, sẽ vẫn cần phải yêu cầu sử dụng nó bằng
<uses-permission>
.
Phần tử
<permission-tree>
sẽ khai báo một vùng tên cho nhóm quyền mà sẽ được định nghĩa trong
mã. Và
<permission-group>
sẽ định nghĩa một nhãn cho một tập hợp quyền (cả được khai báo trong bản kê khai bằng phần tử
<permission>
và được khai báo ở chỗ khác). Nó chỉ ảnh hưởng tới cách các quyền được
nhóm lại khi được trình bày với người dùng. Phần tử
<permission-group>
không quy định những quyền nào thuộc về nhóm;
nó chỉ đặt cho nhóm một cái tên. Một quyền được đặt vào nhóm
bằng cách gán tên nhóm với thuộc tính của phần tử
<permission>
,
permissionGroup
.
Mọi ứng dụng đều được liên kết với thư viện Android mặc định, nó bao gồm các gói cơ bản để xây dựng ứng dụng (bằng các lớp thông dụng chẳng hạn như Hoạt động, Dịch vụ, Ý định, Dạng xem, Nút, Ứng dụng, Trình cung cấp Nội dung, v.v.).
Tuy nhiên, một số gói nằm trong thư viện của chính mình. Nếu ứng dụng của bạn
sử dụng mã từ bất kỳ gói nào trong những gói này, nó phải công khai yêu cầu được liên kết
với chúng. Bản kê khai phải chứa một phần tử
<uses-library>
riêng để đặt tên cho từng thư viện. (Tên thư viện có thể được tìm thấy trong tài liệu
của gói.)