2.1 .Tổng quan về Android
3.2. Thiết lập môi trường phát triển
Ở phần này cung cấp cách cấu hình hệ thống máy chủ để xây dựng Android cho các thiết bị di động cầm tay và có thể thử nghiệm trên hệ điều hành Linux, Ubuntu. Sau đó tiến hành cài đặt những cái mà Android yêu cầu:
Để chỉ ra thủ tục hợp nhất nhân Linux tham chiếu với nhân Android, ta quan sát sơ đồ hình 3.3 với các thành phần chính:
Hình3.3: Thủ tục hợp nhất nhân
- Mainline Kernel: Hạt nhân mainline là hạt nhân được nhận từ mainline. - Reference kernel: Hạt nhân tham chiếu là hạt nhân mà có trong bo mạch,
nó có thể là một hạt nhân mainline, cộng với bản vá lỗi cần thiết để hỗ trợ bo mạch.
- Merge kernel: Hạt nhân hợp nhất là kết quả của việc hợp nhất các bản vá lỗi Android với nhân tham chiếu.
- Android patches: Các bản vá lỗi trích ra từ các hạt nhân Android của Google.
- Android kernel: là có thể nhận được từ kho lưu trữ dự án mã nguồn mở Android của Google. Nó bao gồm những thay đổi của Google cho nhân Mainline để hỗ trợ Android, có thể lấy từ http://android.git.kernel.org/kernel/common.git
a. Hạt nhân tham chiếu Linux
Khi đó người sử dụng nên kiểm tra xem có hạt nhân làm việc và một hệ thống tập tin gốc Linux trên bo mạch. Nghĩa là khi đó ta có thể khởi động vào một môi trường đồ họa GNU/Linux (Lưu ý hệ thống tập tin Linux chỉ được yêu cầu để kiểm tra hạt nhân hợp nhất, mà không cho cổng SoC).
Một hạt nhân mà nó khởi động và cung cấp cho hệ thống tất cả các hỗ trợ thích hợp cần thiết cho một hệ thống cửa sổ như là một điểm tham chiếu gọi là hạt nhân tham chiếu. Như trình điều khiển đồ họa cho bộ đệm khung hoặc chip đồ họa. Các tập tin cấu hình .config của hạt nhân tham chiếu sẽ được sử dụng như một cở sở cho việc hợp nhất nhân, lưu thành một bản sao làm tài liệu tham chiếu cho lần sử dụng sau.
Nhân Android được sửa đổi giống hạt nhân tham khảo, nếu hai hạt nhân có phiên bản không phù hợp với nhau sẽ dẫn đến việc mất nhiều thời gian sát nhập và gỡ lỗi.
c. Hợp nhất thay đổi hạt nhân Android
Trong bước này, có thể có các bản vá lỗi Android từ nguồn hạt nhân Android, sẽ tạo ra một tập tin vá lỗi có thể được áp dụng cho các hạt nhân tham khảo.
Ví dụ như kích thước dự kiến của miếng vá là 2MB, để trích xuất các bản vá lỗi tìm thấy trong thời gian sử dụng git log, nơi hạt nhân Mainline được đưa vào cây nguồn hạt nhân Android.
Sau đó khi đến cấp cao nhất của cây nguồn hạt nhân Android chạy lênh:
git log --pretty=oneline --format="%Cgreen%h %Creset%s" \ --grep="Linux 2.6." -n 20
Sẽ tạo ra 20 mục đăng nhập mà có diễn tả Linux 2.6 trong chủ đề:
521cb40 Linux 2.6.38 a5abba9 Linux 2.6.38-rc8 dd9c154 Linux 2.6.38-rc7 f5412be Linux 2.6.38-rc6 85e2efb Linux 2.6.38-rc5 100b33c Linux 2.6.38-rc4 ebf5382 Linux 2.6.38-rc3 1bae4ce Linux 2.6.38-rc2 c56eb8f Linux 2.6.38-rc1
aa0adb1 batman-adv: Use "__attribute__" shortcut macros f5afcd3 drm/i915/crt:Check for a analog monitor in case of DVI-I
3c0eee3 Linux 2.6.37 387c31c Linux 2.6.37-rc8 90a8a73 Linux 2.6.37-rc7 b0c3844 Linux 2.6.37-rc6 cf7d7e5 Linux 2.6.37-rc5 e8a7e48 Linux 2.6.37-rc4 3561d43 Linux 2.6.37-rc3
5bd5a45 x86: Add NX protection for kernel data 64edc8e x86: Fix improper large page preservation
git diff 521cb40 HEAD > 2.6.38-to-Android.patch
Lệnh này cung cấp một tập tin vá lỗi tên 2.6.38-to-Android.patch có chứa những thay đổi được hợp nhất. Trước khi thực hiện việc sát nhập thực tế ta kiểm tra các xung đột bằng lệnh:
git apply --test [path/to/2.6.38-to-Android.patch]
d. Cấu hình hạt nhân hợp nhất trong Android
Để có được cấu hình hạt nhân hợp nhất phải có cấu hình làm việc được biết đến thử nghiệm với hệ thống tập tin gốc Linux. Điều này cần được kiểm tra bằng cách xây dựng một ảnh nhân từ cây nguồn hợp nhất, sử dụng tập tin .config được lưu trong phần 1a và kiểm tra xem nó khởi động tập tin hệ thống gốc Linux. Nếu nó không khởi động, có thể thêm các tùy chọn để cấu hình làm việc được yêu cầu cho Android. Đó là:
Quản lý năng lượng : CONFIG_PM=y CONFIG_HAS_EARLYSUSPEND=y CONFIG_SUSPEND=y wakelocks : CONFIG_HAS_WAKELOCK=y - CONFIG_WAKELOCK=y - CONFIG_EARLYSUSPEND=y - CONFIG_USER_WAKELOCK=y - CONFIG_FB_EARLYSUSPEND=y ashmem : CONFIG_ASHMEM=y pmem : CONFIG_ANDROID_PMEM=y
hỗ trợ lớp chuyển đổi : CONFIG_SWITCH=y
dàn dựng điều khiển : CONFIG_STAGING=y
- CONFIG_ANDROID=y
- binder : CONFIG_ANDROID_BINDER_IPC=y
- logger :CONFIG_ANDROID_LOGGER=y
- điều khiển ram : CONFIG_ANDROID_RAM_CONSOLE=y
usb_gadgets : - CONFIG_USB_GADGET=y - CONFIG_USB_ANDROID=y - CONFIG_USB_ANDROID_ACM=y - CONFIG_USB_ANDROID_ADB=y - CONFIG_USB_ANDROID_MASS_STORAGE=y - CONFIG_USB_ANDROID_MTP=y
Hỗ trợ năng lượng : CONFIG_POWER_SUPPLY=y
- CONFIG_PDA_POWER=y
Các tên ở bên trên đều có thể được tìm thấy trong cấu hình nhân Android 2.6.38. Để có nhân hợp nhất hoạt động chính xác cho Android, các tùy chọn cấu hình trên là những lựa chọn tối thiểu cần thiết.
e. Xây dựng hạt nhân hợp nhất
Xây dựng hạt nhân hợp nhất với lệnh:
make ARCH=arm CROSS_COMPILE=[path-to-arm-gcc] uImage
sẽ tạo ra một ảnh nhân, uImage và zImage trong thư mục arch/arm/boot của cây nguồn nhân hợp nhất. Thay thế [path-to-arm-gcc] bằng đường dẫn đến phiên bản chuỗi công cụ ARM
Phần 2: Không gian người dùng – Các hệ thống tập tin Android
a. Thêm thiết bị vào cây
Mỗi mục tiêu xây dựng định nghĩa cấu hình của ARM dựa trên bo mạch và lựa chọn các nguồn phải được xây dựng cho Android. Thư mục đích xây dựng là xây dựng hệ thống Android sử dụng phụ thuộc vào các phiên bản Android. Ví dụ phiên bản 2.3 là:
[android_root]/device
Dưới đây là một ví dụ về việc thêm một vài ARM chung để xây dựng target Android. Tạo thư mục trong [android_root]/device
mkdir [android_root]/device/arm
Vào thư mục mới và tạo ra một thư mục các sản phẩm:
mkdir [android_root]/device/arm/products
Trong thư mục products cần một tập tin AndroidProducts.mk để liệt kê tất cả các sản phẩm có trong thư mụcarm
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/armboards_v7a.mk \
$(LOCAL_DIR)/armboards_v7a_noneon.mk \ $(LOCAL_DIR)/another_product.mk \
Mỗi tập tin phải chứa điều chỉnh để phù hợp với sản phẩm và thiết bị đặt tên:
$(call inherit-product,$(SRC_TARGET_DIR)/product/generic.mk) #
PRODUCT_NAME := [product_name] PRODUCT_DEVICE := [board_name]
PRODUCT_NAME là tên của target xây dựng được sử dụng bởi hệ thống xây dựngAndroid
và PRODUCT_DEVICExác định tên của thư mục chứa các tập tin mô tả thiết bị.
Ví dụ: $(call inherit-product,$(SRC_TARGET_DIR)/product/generic.mk) # # Overrides PRODUCT_NAME := armboard_v7a PRODUCT_DEVICE := armboard_v7a
Sau đó nó sẽ tạo ra các thư mục cần thiết
mkdir [android_root]/device/arm/armboard_v7a/
mkdir [android_root]/device/arm/armboard_v7a_noneon/ mkdir [android_root]/device/arm/another_product/
Bây giờ để xây dựng các hệ thống tập tin Android cho SoC với các thư mục thiết bị có chứa tất cả các cấu hình cần thiết và xây dựng tập tin. Như
arm/ +-- armboard_v7a | +-- Android.mk | +-- armboard_v7a.kl | +-- BoardConfig.mk | \-- system.prop +-- armboard_v7a_noneon | +-- Android.mk | +-- armboard_v7a_noneon.kl | +-- BoardConfig.mk | \-- system.prop +-- another_product | +-- Android.mk | +-- another_product.kl | +-- BoardConfig.mk | \-- system.prop \-- products +-- AndroidProducts.mk
+-- armboard_v7a.mk
+-- armboard_v7a_noneon.mk
\-- another_product.mk
b. Xây dựng Android cho SoC
Xây dựng hệ thống tập tin Android cho một trong những target được thêm vào, bằng cách vào thư mục trên cùng của cây mã nguồn Android và nhập:
make PRODUCT-[PRODUCT_NAME]-eng
ví dụ:
make PRODUCT-armboard_v7a-eng
c. Cấu hình tập tin hệ thống gốc
Tập tin hệ thống gốc được sử dụng trên NFS để thiết lập các vị trí muốn đặt hệ thống tập tin gốc Android. Tiếp theo sao chép nội dung của thư mục gốc từ cây nguồn Android tới vị trí NFS:
$cp -a[android_root]/out/target/product/armboard_v7a/root/*\
/var/nfs4/android-fs
d. Khởi động
Tải hạt nhân lên bo mạch và thiết lập các đối số khởi động thích hợp để khởi động thành công.
CHƯƠNG 4: PHÁT TRIỂN PHẦN MỀM TRÊN ANDROID
Phần mềm nhúng là “phần mềm do nhà sản xuất thiết bị cài sẵn vào sản phẩm và chúng được sử dụng ngay cùng với đồ điện tử đó mà không cần có sự cài đặt của người thứ ba”. Tuy nhiên, phần mềm ứng dụng chạy trên thiết bị cầm tay có hệ điều hành Android cũng được coi là phần mềm nhúng. Vì trên thị trường hiện nay, cũng có khá nhiều bộ vi xử lý hỗ trợ chạy trên hệ điều hành Android như bộ vi xử lý ARM, Qualcomm, telechip, nên phần mềm ứng dụng có thể thông qua hệ điều hành để chạy trên thiết bị phần cứng.
Qua nghiên cứu các khả năng hỗ trợ phát triển phần mềm ứng dụng trên hệ điều hành Android trong chương 2 và khả năng tùy chỉnh, tích hợp của Android trong chương 3. Ở chương 4 của luận văn tôi đã tiến hành phát triển phần mềm ứng dụng hỗ trợ người sử dụng tạo Ghi chú, nhằm đánh giá một số tính năng của hệ điều hành Android như hỗ trợ giao diện tương tác với người dùng, hỗ trợ tương tác trao đổi giữa các thành phần.
4.1. Cấu trúc của một ứng dụng
Các thành phần ứng dụng là các khối xây dựng cơ bản của một ứng dụng Android. Mỗi thành phần là một điểm khác nhau mà thông qua đó hệ thống có thể nhập vào ứng dụng của bạn. Cấu trúc của một ứng dụng Androi được chia thành 4 thành phần chính bắt buộc phải khai báo trong AndroidManifest.xml, mỗi loại phục vụ một mục đích riêng và có một vòng đời khác nhau định nghĩa các thành phần được tạo ra và bị phá hủy như thế nào[26]. Bao gồm:
- Activity - Service
- Content Provider - Broadcast Receiver
Và được chia thành 6 loại: Activity, Service, Content Provider, Intent, Broadcast Provider, Notification
4.1.1. Activity
Một activity dùng để hiển thị màn hình, một ứng dụng có giao diện người sử dụng thì ít nhất phải có một Activity. Khi khởi động một ứng dụng nào đó thì main Activity sẽ được gọi và hiển thị giao diện của ứng dụng đó lên màn hình cho phép người dùng tương tác.
Một activity được thực hiện như một lớp con của Activity. Activity là thành phần chính quan trọng nhất trong xây dựng ứng dụng Android, Activity được quản lý theo dạng ngăn xếp. Một Activity mới được khởi tạo được xếp lên đầu của ngăn xếp và trở thành activity hoạt động, còn các Activity trước đó sẽ bị tạm dừng cho đến khi nào Activity mới được giải phóng.
Nhờ vào cơ chế trên Activity chia ra thành 4 trạng thái hoạt động:
active (running ): Activity đang hiển thị trên màn hình (đang hoạt động).
paused: Activity không thể tương tác, nhưng vẫn hiển thị
stop: Activity mới hoạt động sẽ thay thế hoàn toàn Activity cũ, khi đó Activity cũ có trạng thái stop.
killed (shutdown) : Trong trường hợp hệ thống thiếu bộ nhớ thì sẽ giải phóng các tiến trình theo quy tắc ưu tiên. Activity đang ở trạng thái paused hoặc stop bị giải phóng, nếu muốn các Acticity này hoạt động trở lại phải khởi động lại hoàn toàn.
Sơ đồ ở hình 4.1 dưới đây biểu diễn đường đi trạng thái của Activity. Hình chữ nhật đại diện cho các phương thức được gọi. Hình oval màu là các trạng thái chính của Activity.
Khi thay đổi trạng thái thi các phương thức là những liên kết móc nối mà bạn có thể ghi đè đề tương thích công việc trong ứng dụng. Trong một Activity có 7 phương thức được định nghĩa trong đó, bao gồm:
- onCreate(): Một Activity xây dựng cần viết phương thức onCreate() để thực hiện quá trình khởi tạo. Tại phương thức này ta có thể làm một số các cài đặt tĩnh như : tạo View, kết nối dữ liệu đến danh sách,.. Phương thức onStart() luôn theo sau.
- onRestart(): từ trạng thái stop, Activity được hiển thị lại. Phương thức onStart() luôn theo sau.
- onStart(): được gọi khi một hoạt động sẵn sàng với người dùng. Theo sau là onResume() nếu Activity ở trạng thái ẩn hoặc onStop().
- onResume(): Khi Activity bắt đầu tương tác với người dùng. Luôn theo sau là onPause().
- onPause(): khi một Activity mới được bật lên trên Activity hiện tại, làm cho người sử dụng không thao tác được với Activity cũ, mặc dù vẫn có thể nhìn thấy. Có thể Activity bị tiêu diệt bởi hệ thống.
- onStop(): người dùng không còn nhìn thấy Activity hiện tại, có thể Activity bị tiêu diệt bởi hệ thống.
- onDestroy(): Activity không còn tồn tại nữa, có thể Activity bị tiêu diệt bởi hệ thống.
Hình 4.1: Vòng đời của một ứng dụng
4.1.2. Service
Một dịch vụ là một thành phần chạy ẩn để thực hiện các hoạt động hoặc thực hiện công việc cho các tiến trình từ xa. Một dịch vụ không cung cấp giao diện người dùng. Ví dụ, người sử dụng có thể vừa sử dụng dịch vụ nghe nhạc vừa thực hiện được ứng dụng khác.
Một dịch vụ được thực hiện như một lớp con của Service. Mỗi lớp của Service phải chứa thẻ <service> được khai báo trong AndroidManifext.xml. Tương tự như các đối tượng khác của ứng dụng, thì các service chạy trên luồng Thread của tiến trình chính, khi xảy ra tắc nghẽn service sẽ tự sinh ra luồng Thread của nó để thực hiện các tác vụ trong Service.
Có 2 cách gọi Service:
Context.startService(): nó có thể được bắt đầu và cho phép chạy cho đến khi bị dừng hoặc tự nó dừng. Khi kết thúc service chỉ cần gọi stopService(). Một service được bắt đầu bởi phương thức startService() là service dùng để thực hiện các tác vụ ẩn dưới nền. Xem hình 2.6 dưới.
Context.bindService(): cho phép một kết nối lâu dài được thực hiện với Service để tương tác với nó. Một service được bắt đầu bởi phương thức bindService() là service được dùng để cung cấp các chức năng cho các chương trình khác. Xem hình 4.2 dưới.
Hình 4.2 : Hai cách gọi Service
4.1.3. Content Provider
Một nhà cung cấp nội dung quản lý một bộ chia sẻ dữ liệu ứng dụng. Bạn có thể lưu trữ các dữ liệu trong file hệ thống, một cơ sở dữ liệu SQLite, trên trang web hoặc
bất kỳ vị trí lưu trữ nào khác mà ứng dụng của bạn có thể truy cập. Thông qua nhà cung cấp nội dung, các ứng dụng khác có thể truy vấn hoặc sửa đổi dữ liệu.
Một nhà cung cấp nội dung được thực hiện như một lớp con của ContentProvider.
4.1.4. Intent
Intent miêu tả một hành động được thực hiện, dùng Intent ta có thể đưa ra một thông báo đến toàn hệ thống, một Activity hoặc một Service.
4.1.5. Broadcast Receiver
Dùng đề nhận và phản hồi các thông báo mà hệ thống phát đi. Broadcast Receiver không hiển thị giao diện người dùng. Tuy nhiên chúng có thể khởi động một Activity khi phản hồi thông tin vừa nhận được hoặc dùng NotificationManager để thông báo.
Một broadcast receiver được thực hiện như một lớp con của BroadcastReceiver.
4.1.6. Notification
Giúp đưa ra tín hiệu thông báo cho người dùng mà không cần ngắt quãng các hành động hiện tại. Ví dụ, thông báo có tin nhắn hoặc email gửi đến có thể thông báo bằng âm thanh, đèn nhấp nháy.
4.2. Xây dựng ứng dụng
4.2.1. Mục tiêu của ứng dụng
Một thiết bị cầm tay khi có cài đặt hệ điều hành Android theo từng phiên bản khác nhau, nên khả năng hỗ trợ một số chức năng cũng khác nhau. Tuy nhiên, theo thống kê các chức năng và các phần mềm ứng dụng chính hỗ trợ có sẵn trong một thiết bị cầm tay gồm có:
- Chức năng cài đặt hiển thị màn hình, âm thanh, ngày giờ, ngôn ngữ. - Chức năng nhắn tin, đàm thoại.
- Ứng nghe nhạc. - Ứng dụng bản đồ.
- Chức năng quản lý hình ảnh, camera hỗ trợ.
Ngoài ra, còn do tính tiện lợi của thiết bị là có thể sử dụng và mang theo mọi lúc mọi nơi, nên có thể sử dụng thay một số những vật dụng hỗ trợ người sử dụng trong công việc cũng như sách, vở viết, bút viết,… Cũng như, nhằm hỗ trợ người sử dụng có thể hiểu được về khả năng hỗ trợ tương tác giữa các thành phần trên Android, giúp họ phát triển được các phần mềm ứng dụng có thể chạy được trên nền tảng