Hãy kể tên các thành phần ứng dụng của một project android ?

Để tiếp tục xây dựng cho ứng dụng Reminder, sau khi đã cài đặt thành công máy ảo Genymotion ở bài trước, hôm nay chúng ta tiếp tục tìm hiểu tổng quan về cách thức tổ chức một ứng dụng trong Android, với cái nhìn tổng quan này, chúng ta sẽ biết một ứng dụng trong Android được tổ chức bởi các thành phần cấu tạo nào, thành phẩn nào là quan trọng, và những thành phần đó được sắp đặt như thế nào bên trong một ứng dụng, từ đó sẽ làm bước đệm căn bản cho viêc phát triển ứng dụng Reminder của chúng ta hoặc các ứng dụng khác của chính các bạn sau này.

Các thành phần cơ bản của một ứng dụng

Chúng ta khảo sát sơ qua các phần liệt kê dưới đây, đây là cái nhìn tổng quan ban đầu cho một cấu trúc của ứng dụng:

  • Một ứng dụng Android được tạo thành bởi một trong các Thành phần [trong kỹ thuật ta gọi là Application Components]. Mỗi thành phần cung cấp một cách thức khác nhau để hệ điều hành làm việc với ứng dụng. Mỗi thành phần tồn tại như một thực thể riêng và đóng một vai trò nhất định giúp xác định hành vi tổng thể của ứng dụng của bạn. Có 4 loại thành phần khác nhau trong Android:
    • Activities
    • Services
    • Content Providers
    • Broadcast Receivers
  • Ba trong bốn thành phần kể trên đây: Activities, Services và Broadcast Receiver được thực thi bởi một Intent. Intent là một thông điệp bất đồng bộ mà ta sẽ khảo sát ngay sau đây.
  • Một file Manifest dùng để khai báo với hệ thống các thành phần có thể có và khai báo các yêu cầu của ứng dụng. Manifest cũng sẽ được nói cụ thể hơn ở phần sau.
  • Cuối cùng, ứng dụng Android không thể thiếu Resources,  resources là phẩn tách biệt với source code của ứng dụng, cho phép ứng dụng sử dụng các hình ảnh, âm thanh, font chữ,… làm phong phú thêm các yêu cầu của ứng dụng.

Chúng ta sẽ làm rõ từng phần kể trên ở các định nghĩa sau đây.

Activities

  • Activity đại diện cho một màn hình duy nhất với một giao diện người dùng mà ở đó người dùng có thể quan sát và tương tác. Ví dụ như một ứng dụng email có một Activity hiển thị danh sách các email, một Activity khác cung cấp một giao diện để soạn thảo email, và một Activity khác nữa cung cấp một giao diện để đọc email,…
  • Mặc dù các Activity này liên kết chặt chẽ với nhau trong ứng dụng email như ví dụ trên nhằm đem lại trải nghiệm tốt nhất cho người dùng nhưng thực tế chúng hoàn toàn độc lập với nhau.
  • Các ứng dụng khác [có thể không phải ứng dụng của ta xây dựng] hoàn toàn có thể khởi chạy các Activity mà chúng ta định nghĩa, dĩ nhiên trong trường hợp ứng dụng email của chúng ta cho phép.
  • Mỗi một ứng dụng đều có một “main activity”, đây là Activity sẽ được hiển thị đầu tiên khi ứng dụng được khởi chạy, một ứng dụng sẽ có một main activity và thông thường sẽ phải có thêm nhiều Activity khác.
  • Một Activity có thể khởi chạy các Activity khác. Mỗi lần một Activity mới được khởi chạy thì Activity trước đó bị stop và hệ thống sẽ lưu Activity stop này vào một back stack. Việc quay lại các Activity trước đó [khi người dùng nhấn vào nút back trên thiết bị chẳng hạn] thì hệ thống chỉ đơn giản lấy các Activity đã lưu trữ trong back stack, và Activity được lấy trong back stack này tiếp tục sẽ được hiển thị lên màn hình người dùng. Back stack kể trên được tổ chức theo đúng tiêu chí của một stack, đó là “vào sau, ra trước” [last in, first out], chúng ta có thể tìm hiểu thêm về stack bằng cách search trên Google hoặc ở nguồn này //en.wikipedia.org/wiki/Stack_[abstract_data_type].
  • Để hình dung rõ ràng hơn về việc back stack làm việc với các Activity như thế nào, ta hãy xem sơ đồ sau.

  • Ở sơ đồ trên, khi ứng dụng được khởi chạy, một main activity sẽ được kích hoạt ban đầu, ví dụ như trên ta thấy main activity chính là Activity 1, Activity 1 sẽ được tự động chứa trong back stack và đang ở dạng foreground, tức là đang được hiển thị lên màn hình. Sau đó Activity 1 này sẽ start một Activity khác [do hành vi người dùng nhấn vào một button nào đó, hoặc Activity 1 tự động start Activity 2 theo timer được định sẵn theo kịch bản chẳng hạn], như hình ta thấy Activity 2 được hiển thị ở foreground, tức là lúc này Activity 2 sẽ thay Activity 1 hiển thị lên màn hình, Activity 1 sẽ không mất đi mà chỉ tạm stop lại rồi được lưu giữ ở back stack. Sau đó Activity 2 lại start Activity 3, và cũng như trên, Activity 3 sẽ giữ vai trò foreground, còn Activity 2 và Activity 1 thì tiếp tục được lưu giữa trong back stack. Đến lúc này nếu người dùng nhấn nút back trên thiết bị, thì Activity 3 sẽ bị lấy ra khỏi stack, chính lúc này Activity 3 mới bị destroy, tức là bị hủy luôn không thuộc diện quản lý của back stack, vai trò foreground hiển thị lên màn hình được nhường lại cho Activity kế đó bị đưa vào back stack lúc trước đó là Activity 2. Cứ như vậy nếu người dùng tiếp tục nhấn nút back thì Activity 1 lại tiếp tục được hiển thị ra foregroud còn Activity 2 bị hủy. Nếu người dùng lại tiếp tục nhấn back nữa thì Activity 1 cũng bị hủy khỏi back stack, lúc này ứng dụng xem như bị đóng lại [ngừng hoạt động]. Để hiểu rõ hơn hoạt động của back stack, có thể xem thêm thông tin ở trang //developer.android.com/guide/components/tasks-and-back-stack.html.

Services

  • Một Service là một thành phần chạy ngầm, để thực hiện các hoạt động lâu dài hoặc để thực hiện công việc cho các xử lý từ xa [remote processes].
  • Service không cung cấp giao diện người dùng. Ví dụ một service có thể chơi nhạc trong khi người dùng đang sử dụng một ứng dụng khác.
  • Một thành phần [application component] khác chẳng hạn như một activity có thể khởi động một service để nó chạy độc lập hoặc liên kết để tương tác với nó.
  • Một service về cơ bản có 2 loại:
    • Started:
      • Khi được khởi động lên, thì service loại này sẽ hoạt động ở nền [background] vô thời hạn, dù cho thành phần khởi chạy nó đã kết thúc.
      • Thông thường một started service chỉ được giao cho một xử lý đơn lẻ và không trả kết quả về cho thành phần đã gọi nó.
    • Bound:
      • Một bound service cung cấp một giao diện client-server để cho phép các thành phần có thể tương tác được với nhau.
      • Thời gian sống của một bound service phụ thuộc vào thành phần liên kết [bound] với nó, tức là thành phần liên kết còn tồn tại thì bound service  còn tồn tại và ngược lại.
      • Nhiều thành phần có thể liên kết với một bound service tại một thời điểm, nhưng khi tất cả các thành phần này đều ngưng liên kết [unbind] thì service loại này cũng bị hủy theo.
  • Service sẽ được đề cập chi tiết hơn ở các bài học buổi khác.

Content Providers

  • Content Provider quản lý một tập hợp các dữ liệu được chia sẻ của ứng dụng. Thông qua Content Provider, các chương trình khác có thể truy xuất hoặc thậm chí thay đổi các dữ liệu của một ứng dụng [nếu Content Provider cho phép].
  • Ví dụ hệ điều hành Android cung cấp một Content Provider quản lý danh bạ điện thoại. Thông qua Content Provider này mà các ứng dụng [có các quyền thích hợp] có thể đọc hoặc thêm thông tin vào danh bạ điện thoại này.
  • Content Provider dĩ nhiên còn hữu ích cho cả việc đọc và ghi dữ liệu private của ứng dụng và không chia sẻ ra ngoài.

Broadcast Receivers

  • Broadcast Reveiver là một thành phần dùng để trả lời các thông điệp được phát ra từ hệ thống.
  • Trong quá trình thiết bị di động vận hành có rất nhiều thông điệp khác nhau được hệ thống thông báo như: màn hình đã tắt, pin yếu, đã chụp xong một tấm hình,…
  • Một Broadcast Receiver không tạo một giao diện người dùng nhưng nó có thể tạo một thông báo [notification] trên thanh trạng thái [status bar] để báo động người dùng khi một sự kiện nào đó xảy ra.

Intent

  • Ba trong số bốn loại thành phần của ứng dụng [activity, service, broadcast receiver] đều được khởi chạy bởi một lời gọi bất đồng bộ, ta gọi là Intent.
  • Intent tạo nên một cơ sở gắn kết giữa các thành phần trong ứng dụng lại với nhau.
  • Intent cũng sẽ được đề cập chi tiết hơn nữa ở bài sau.

File Manifest

  • File Manifest là nơi ứng dụng của bạn sẽ trình bày với hệ thống rằng “có những gì trong ứng dụng này”, như:
    • Đăng ký các user permission, tạm hiểu là các quyền hạn mà người dùng xin phép để sử dụng các tính năng của hệ thống, như là quyền được truy cập Interner, được đọc danh bạ [contacts], được ghi file ra thẻ nhớ ngoài,…
    • Chỉ định Minimum Required SDK, là hệ điều hành thấp nhất của Android mà ứng dụng của ta hỗ trợ, thông số này được tạo ra khi chúng ta tạo một ứng dụng mới ở Bài 2, khi đó chúng ta đã chỉ ra Minimum Requied SDK và thông số chúng ta chỉ định đó sẽ được lưu vào thuộc tính này của file Manifest.
    • Chỉ định các tính năng phần cứng và phần mềm mà ứng dụng của ta muốn sử dụng đến, như camera, bluetooth, hay ngay cả tính năng multitouch.
    • Một số các thư viện bên ngoài [bên ngoài ở đây có thể hiểu là các thư viện không có sẵn trong các API Framework của chúng ta] mà ứng dụng của ta có sử dụng đến, như thư viện Google Maps, Google Play,…
  • Khi tạo mới một ứng dụng, ADT sẽ tự động tạo cho chúng ta một file AndroidManifest.xml, chúng ta có thể làm theo các bước sau để xem cụ thể một file Manifest sẽ trông như thế nào.
  • Trong Eclipse, tìm đến cửa sổ Package Explorer, tìm đến project Reminder của chúng ta đã tạo trước đó, ta tìm file Manifest trong cây thư mục của project Reminder này như hình sau, click đúp vào file Manifest để mở nó lên [lưu ý là click đúp, vì một số bạn nếu đã lập trình iOS trước đó sẽ quen với việc click đơn để mở một file trong Xcode, trong Eclipse thì khác, khi muốn mở một file ta phải click đúp].

  • Bất cứ một file xml nào, kể cả file Manifest.xml lẫn các file resource xml cũng đều mặc định ban đầu được mở lên với một màn hình có nhiều tab bên dưới, mục đích của màn hình này là sẽ cung cấp cho chúng ta có được nhiều tùy chọn hơn trong việc review và tùy chỉnh nội dung của file xml. Thường thì các tab đầu sẽ cung cấp một số các giao diện chỉnh sửa, còn tab cuối sẽ là các đoạn code xml cho chúng ta chỉnh sửa thủ công bằng tay. Trong các bài này và các bài sau chúng ta tập chung chủ yếu vào việc review và chỉnh sửa các file xml một cách thủ công bằng tay, vừa chính xác lại dễ quản lý sau này, hơn là các giao diện tự động sẽ làm rối file xml của chúng ta hơn nữa, bởi vì Eclipse không phải là một công cụ chuyên biệt cho Android, nên các giao diện tự động của Eclipse [có cả của ADT nhúng vào] sẽ không đảm bảo và dễ gây ra các lỗi ngớ ngẩn khó chịu sau này.

  • Như đã nói ở trên, chúng ta nhìn vào dãy tab bên dưới và click vào tab AndroidManifest.xml để mở code xml ra review. Tôi khuyên bạn nên chọn lần lượt từng tab và có cái nhìn tổng quan trước mỗi tab như thế nào, vì tùy thuộc mỗi người sẽ chọn cho mình một phong cách làm việc sau này, đối với tôi thì tôi thích sửa code xml, nhưng bạn có thể sử dụng các cách thức khác hiệu quả hơn đối với bản thân bạn thì càng tốt.

  • Dưới đây sẽ giải thích một số ý nghĩa và cách sử dụng của các tag trong AndroidManifest.xml
    • là thẻ gốc. Thuộc tính quan trọng mà bạn cần quan tâm trong thẻ này là package. Cũng như Minimum Required SDK, package xuất hiện sau khi bạn  tạo một ứng dụng mới ở Bài 2, khi đó bạn đã khai báo một package name và cái tên chúng ta đã chỉ chỉ định khi đó sẽ được lưu vào trường này của file Manifest. Ngoài ý nghĩa của package name đã được giải thích ở Bài 2, package còn chỉ ra đây là tên gốc của ứng dụng, để đến khi bạn cần cung cấp một class mới ở bất cứ nơi nào khác trong file Manifest này, bạn chỉ việc đặt một dấu chấm [.] đằng trước thay cho cả đường dẫn của package gốc. Như ví dụ trên thay vì cung cấp tên đầy đù cho MainActivity là android:name=”com.example.reminder.MainActivity” thì ta chỉ cần ghi vắn tắt là android:name=”.MainActivity”.
    • xác định phiên bản hệ điều hành để chạy được chương trình. Cũng như các thuộc tính trên, thuộc tính của trường này cũng được tạo ra sau khi ta chỉ định các giá trị Minimum Requires SDK và Target SDK khi tạo project mới ở Bài 2.
    • là thẻ quan trọng nhất trong file này. Nó chỉ định ra các thành phần có trong một ứng dụng.
      • android:icon là thuộc tính chỉ định hình ảnh dùng làm icon cho ứng dụng của chúng ta, bạn có thể thay đổi đường dẫn cho icon của ứng dụng bằng cách thay đổi tên hình trong trường này.
      • android:label là thuộc tính chỉ ra dòng text nào sẽ được dùng làm tên của ứng dụng, cả 2 thuộc tính kể trên đây đều tùy thuộc vào bạn tạo mới một ứng dụng ở Bài 2, khi bạn chỉ định một Application Name và một icon cho nó.
    • khai báo một Activity, nó bao gồm các thuộc tính cơ bản sau:
      • android:name khai báo tên và đường dẫn đến một Activity, tất nhiên đường dẫn này chính là package mà Activity đó nằm trong, và chúng ta có thể không cần khai báo full package name mà chỉ cần đại diện bằng dấu [.] nếu package name của Activity này trùng với trường package đã khai báo ở tag như đã nói ở trên.
      • android:label chỉ định tên cho Activity, tên này sẽ xuất hiện trên title bar của ứng dụng khi Activity này hiển thị, như hình bên dưới.
    • xác định xem trong điều kiện khi nào thì Activity mà thẻ này đang nằm trong đó được hiển thị. Như hình trên kia, thẻ này xác định Activity chứa nó là Activity chính của chương trình và sẽ là Activity xuất hiện đầu tiên khi người dùng start ứng dụng.
  • Dĩ nhiên những gì đã đề cập trên đây chỉ là một phần của file Manifest, vì được dùng để định nghĩa tất cả những gì có trong ứng dụng nên file Manifest rất quan trọng, sẽ được đề cập nhiều hơn nữa ở bài sau.

Resources

  • Một ứng dụng không thể thiếu các resource, đó là các hình ảnh, font chữ, màu sắc, âm thanh… dùng để tăng thêm sự phong phú và tính thẩm mỹ cho ứng dụng. Ở bài tổng quan này chúng ta tìm hiểu một các sơ lược về resource, cụ thể như thế nào sẽ được làm rõ hơn trong các bài sau.
  • Thông thường khái niệm resource trong Android được hiểu như là một cái gì đó tách biệt với source code, source code là nơi chứa đựng java code và các logic của ứng dụng, trong khi resource là những gì còn lại của ứng dụng không phải là source code.
  • Resource được chứa đựng trong thư mục res/ [bạn có thể nhìn vào Package Explorer để thấy thư mục Resource này], trong thư mục này còn có rất nhiều thư mục khác giúp nhóm các resource theo loại và theo các tính năng mà resource đó hỗ trợ.
  • Cụ thể từng loại và tính năng của resource được nói rõ hơn ở bài sau, ở đây ta chỉ nhắc đến 2 loại resource lớn.
    • Default resources: là tất cả các resource mà chúng ta không cần quan tâm đến việc hiển thị khác nhau như thế nào trong các thiết bị, resource này sẽ hiển thị default như những gì nó được cung cấp ở tất cả các thiết bị.
    • Alternative resources: là các resosurce sẽ phụ thuộc vào cụ thể thiết bị mà ta đã chỉ định, chẳng hạn ta muốn ứng dụng chạy trên thiết bị có ngôn ngữ mặc định là tiếng Việt sẽ phải load các text tiếng Việt, hình ảnh cờ Việt,.. còn nếu ứng dụng chạy trên thiết bị có ngôn ngữ mặc định là tiếng Anh sẽ load các text tiếng Anh, hình ảnh cờ Anh,…

Video liên quan

Chủ Đề