lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Bản kê khai Ứng dụng

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:

  • Nó đặt tên gói Java cho ứng dụng. Tên gói đóng vai trò như một mã nhận diện duy nhất cho ứng dụng.
  • Nó mô tả các thành phần của ứng dụng — hoạt động, dịch vụ, hàm nhận quảng bá, và trình cung cấp nội dung mà ứng dụng được soạn bởi. Nó đặt tên các lớp triển khai từng thành phần và công bố các khả năng của chúng (ví dụ, những tin nhắn Intent mà chúng có thể xử lý). Những khai báo này cho phép hệ thống Android biết các thành phần là gì và chúng có thể được khởi chạy trong những điều kiện nào.
  • Nó xác định những tiến trình nào sẽ lưu trữ các thành phần ứng dụng.
  • Nó khai báo các quyền mà ứng dụng phải có để truy cập các phần được bảo vệ của API và tương tác với các ứng dụng khác.
  • Nó cũng khai báo các quyền mà ứng dụng khác phải có để tương tác với các thành phần của ứng dụng.
  • Nó liệt kê các lớp Instrumentation cung cấp tính năng tạo hồ sơ và các thông tin khác khi ứng dụng đang chạy. Những khai báo này chỉ xuất hiện trong bản kê khai khi ứng dụng đang được phát triển và thử nghiệm; chúng bị loại bỏ trước khi ứng dụng được công bố.
  • Nó khai báo mức tối thiểu của API Android mà ứng dụng yêu cầu.
  • Nó liệt kê các thư viện mà ứng dụng phải được liên kết với.

Cấu trúc của Tệp Bản kê khai

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>

Các Quy ước Tệp

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:

Phần tử
Chỉ các phần tử <manifest><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.)

Thuộc tính
Theo cách hiểu thông thường, tất cả thuộc tính đều mang tính tùy chọn. Tuy nhiên, có một số thuộc tính phải được quy định cho một phần tử để hoàn thành mục đích của nó. Sử dụng tài liệu làm hướng dẫn. Đối với những thuộc tính thực sự tùy chọn, nó đề cập tới một giá trị mặc định hoặc thông báo điều gì sẽ xảy ra nếu không có một đặc tả.

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ố android:— ví dụ, 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.

Khai báo tên lớp
Nhiều thuộc tính tương ứng với các đối tượng Java, bao gồm các phần tử cho chính ứng dụng (phần tử <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 (Activity, Service, BroadcastReceiver, và ContentProvider), lớp con sẽ được khai báo thông qua một thuộc tính name. Tên phải bao gồm chỉ định gói đầy đủ. Ví dụ, một lớp con 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ở.

Nhiều giá trị
Nếu có thể quy định nhiều hơn một giá trị, phần tử gần như luôn được lặp lại, thay vì liệt kê nhiều giá trị trong một phần tử duy nhất. Ví dụ, một bộ lọc ý định có thể liệt kê vài hành động:
<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>
Giá trị tài nguyên
Một số thuộc tính có các giá trị có thể được hiển thị với người dùng — ví dụ, một nhãn và một biểu tượng cho một hoạt động. Giá trị của những thuộc tính này cần được cục bộ hóa và vì thế phải được thiết đặt từ một tài nguyên hoặc chủ đề. Giá trị tài nguyên được biểu diễn theo định dạng sau,

@[<i>gói</i>:]<i>kiểu</i>:<i>tên</i>

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 '?' thay vì '@' ở đầu:

?[<i>gói</i>:]<i>kiểu</i>:<i>tên</i>

Giá trị xâu
Trường hợp giá trị của một thuộc tính là một xâu, phải sử dụng hai dấu xuyệc ngược ('\\') để thoát các ký tự — ví dụ, '\\n' đối với một dòng tin tức hoặc '\\uxxxx' đối với một ký tự Unicode.

Các Tính năng Tệp

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.

Bộ lọc Ý định

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 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.

Biểu tượng và Nhãn

Nhiều phần tử có thuộc tính iconlabel 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 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 iconlabel 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 "android.intent.action.MAIN" và "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.

Quyền

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:

android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
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 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 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 permission được đặt thành một quyền được khai báo ở nơi khác (chẳng hạn như 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 .

Thư viện

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.)