Tải bản đầy đủ (.pdf) (35 trang)

lập trình ứng dụng game trên android

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.35 MB, 35 trang )

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA CÔNG NGHỆ PHẦN MỀM




BÁO CÁO CUI K
Môn  ÁN MÔN HC
CHUYÊN NGÀNH
 tài : Lp trình ng dng game trên Android


Giảng viên :
ThS. Nguyễn Trác Thức
Sinh viên:
Nguyễn Công Huy 08520148
Võ Trường Thi 08520375



TP.HCM, ngày 01 tháng 06 năm 2012

LI M U
Ngày nay, điện thoại di động là một vật dụng không thể thiếu được trong cuộc sống. Nó
không chỉ có chức năng nghe gọi, mà còn có thể thực hiện được hầu hết những công việc
mà máy tính có thể làm, phục vụ cho nhu cầu văn phòng, giải trí và công việc.
Đặc biệt trong ngành phần mềm, game là một lĩnh vực đặc biệt, đang có bước phát triển
mạnh mẽ, khi mà nhu cầu giải trí trên các thiết bị di động của người sử dụng ngày một
tăng cao. Do đó, lập trình game trên các thiết bị di động đang là một xu hướng tất yếu của
các nhà làm phần mềm.
Điện thoại Android với số lượng người dùng đông đảo, cùng với sự đa dạng về cấu hình,


đa dạng về chủng loại, đang là mảnh đất màu mỡ cho các nhà phát triển game. Do đó,
google cũng đã hỗ trợ Android rất nhiều những thư viện để lập trình game hiệu quả, trong
đó có thể kể đến OpenGL, một thư viện đồ họa rất mạnh mẽ.
Với sự phát triển mạnh mẽ như vậy của Android, và lập trình game trên Android, cơ hội
cho lập trình viên là rất lớn. Vì vậy, nhóm đã chọn đề tài “Lập trình ứng dụng game trên
Android”. Trong đề tài này, nhóm sẽ trình bày cái nhìn cơ bản về lập trình game trên
Android và demo một ứng dụng game trong đó.
Cảm ơn thầy Nguyễn Trác Thức đã tận tình hướng dẫn chúng em hoàn thành đồ án này.

Mục lục
1. Tìm hiểu về Android. 1
1.1. Giới thiệu 1
1.2. Cấu trúc hệ thống 1
1.3. Các thành phần cơ bản của một ứng dụng Android. 4
2. Kỹ thuật lập trình game trên Android. 11
2.1. Thư viện đồ họa OpenGL 11
2.2. Thư viện âm thanh OpenAL 13
2.3. NDK 15
2.4. Lưu trữ thông tin. 18
2.5. Các thư viện khác. 22
2.6. Vòng đời của một game. 22
3. Những khác biệt so giữa lập trình game trên thiết bị di động và trên máy tính. 24
4. Những khác biệt so giữa lập trình game trên Android và các nền tảng di động khác.
26
5. Giới thiệu game Kim cương 27
5.1. Giới thiệu cơ bản 27
5.2. Giao diện người dùng 27
5.3. Cách chơi. 29
5.4. Tính năng mở rộng (item, mission) 30
5.5. Những điểm hấp dẫn trong game. 30




Báo cáo môn Đồ án môn học chuyên ngành Trang 1

1. Tìm hiểu về Android.
1.1. Giới thiệu

Android là một hệ điều hành dành cho các thiết bị di động, được phát triển
bởi Open Handset Alliance, dẫn đầu bởi Google.
Android được phát triển bởi Google, dựa trên nền tảng Linux và các phần
mềm nguồn mở. Ban đầu nó được phát triển bởi Android Inc (sau đó được
Google mua lại) và gần đây nó trở thành một trong những phần mềm đứng
đầu của liên minh OHA (Open Handset Alliance - với khoảng 78 thành
viên bao gồm cả nhà sản xuất, nhà phát triển ứng dụng cho thiết bị di
dộng mà dẫn đầu là Google).
Android được phát triển nhằm cạnh tranh với các hệ điều hành di động
khác như iOS (Apple), BlackBerry OS, Windows Mobile (Microsoft),
Symbian (Nokia), Samsung (Bada), WebOS (Palm) Theo thống kê trong
quý II năm 2010 tại Mỹ, hệ điều hành Android chiếm thị phần 33% (cao
nhất) trong tổng số các hệ điều hành di động được bán ra, thứ 2 là
BlackBerry OS 28% và iOS (Apple) xếp thứ 3 với 22%.
1.2. Cấu trúc hệ thống
Android gồm các tầng thành phần như sau : Application, Application
Framework, Libraries, Linux Kernel.

Báo cáo môn Đồ án môn học chuyên ngành Trang 2


Các tầng cơ bản của nền tảng Android

1.2.1. Applications
Android cung cấp một bộ các ứng dụng tiện ích như email client, SMS,
lịch, bản đồ, trình duyệt … Tất cả đều được viết bằng ngôn ngữ Java.
1.2.2. Application Framework.
Cung cấp một nền tảng mở cho các lập trình viên, giúp họ lập trình ra
những phần mềm với nhiều tính năng thú vị. Ở tầng này, Android cung
cấp khả năng truy cập tới phần cứng hệ thống, cũng như các dịch vụ hệ
điều hành cung cấp như thông tin vị trí, truy cập mạng, thông báo …
Tầng này bao gồm các thành phần sau :
- Một bộ các đối tượng View để xây dựng nên các ứng dụng bao gồm
list, grid, textboxes, buttons, và trình duyệt nhúng.
- Content Providers cung cấp khả năng truy cập tới các dữ liệu của các
ứng dụng khác.
- Resource Manager cung cấp khả năng truy cập tới các resource
không phải dạng code, như chuỗi, đồ họa và layout.
Báo cáo môn Đồ án môn học chuyên ngành Trang 3

- Notification Manager giúp hiện các alert lên status bar.
- Activity Manager cung cấp khả năng quản lý vòng đời của ứng
dụng.
1.2.3. Libraries.
Android bao gồm một bộ các thư viện C/C++ sử dụng bởi các thành
phần khác nhau. Một số thư viện Android được sử dụng như :
- System C library : Thư viện chuẩn C.
- Thư viện đa phương tiện : dựa trên PacketVideo's OpenCORE, thư
viện hỗ trợ chơi các định dạng âm thanh và video phổ biến như
MPEG4, H.264, MP3, AAC, JPG, PNG…
- Quản lý surface : Quản lý việc truy cập các hệ thống hiển thị bên
dưới, các lớp đồ họa 2D, 3D.
- LibWebCore : Một engine trình duyệt hiện đại, được sử dụng trong

cả trình duyệt Android và WebView control.
- SGL : Cơ sở của đồ họa 2D
- 3D libraries : thư viện đồ họa 3D OpenGL, sử dụng tăng tốc đồ họa
nếu phần cứng cho phép.
- FreeType : thư viện render vector và bitmap font.
- SQLite : Engine hệ quản trị cơ sở dữ liệu mạnh mẽ và nhẹ.
1.2.4. Android Runtimes
Mỗi ứng dụng Android chạy trên một tiến trình riêng, với một máy ảo
Dalvik. Máy ảo này thực thi file .dex, một dạng file được tối ưu cho bộ
nhớ nhỏ.
1.2.5. Nhân linux
Android dựa trên nhân linux 2.6 cho những dịch vụ hệ thống như bảo
mật, quản lý bộ nhớ, network stack và driver model. Nhân cũng được
coi như là một lớp ảo trung gian giữa phần cứng và phần mềm.
Báo cáo môn Đồ án môn học chuyên ngành Trang 4

1.3. Các thành phần cơ bản của một ứng dụng Android.
Một ứng dụng Android được tạo bởi một hay nhiều thành phần cơ bản dưới
đây:
1.3.1. Activity
Activity là thành phần có nhiệm vụ hiển thị ra giao diện của ứng dụng.
Một ứng dụng có thể bao gồm nhiều Activity. Chúng tồn tại độc lập với
nhau, nhưng cũng có thể gọi lẫn nhau. Một ứng dụng cũng có thể gọi tới
Activity của một ứng dụng khác (nếu được ứng dụng kia cho phép).
• Vòng đời của Activity

Actitvity là thành phần quan trọng nhất và đóng vai trò chính trong xây
dựng ứng dụng Android.

Hệ điều hành Android quản lý Activity theo dạng stack: khi một

Activity mới được khởi tạo, nó sẽ được xếp lên đầu của stack và trở
thành running activity, các Activity trước đó sẽ bị tạm dừng và chỉ hoạt
động trở lại khi Activity mới được giải phóng.

Các trạng thái trong Activity:
Báo cáo môn Đồ án môn học chuyên ngành Trang 5


Running: Activity đang hiển thị trên màn hình (foreground).
Paused: Activity vẫn hiển thị (visible) nhưng không thể tương tác (lost
focus)
Stop: Activity bị thay thế hoàn toàn bởi Activity mới sẽ tiến đến trạng
thái stop
Báo cáo môn Đồ án môn học chuyên ngành Trang 6

Killed: Khi hệ thống bị thiếu bộ nhớ, nó sẽ giải phóng các tiến trình
theo nguyên tắc ưu tiên. Các Activity ở trạng thái stop hoặc paused cũng
có thể bị giải phóng và khi nó được hiển thị lại thì các Activity này phải
khởi động lại hoàn toàn và phục hồi lại trạng thái trước đó.


• Khởi động Activity

- Khai báo tường minh: cung cấp chính xác thông tin của activity cần
gọi (nếu cùng ứng dụng chỉ cần cung cấp tên class, nếu ứng dụng
khác nhau thì cung cấp tên package, tên class)

Ví dụ: Gọi Activity tường minh

Intent intent = new Intent(getApplicationContext(),

TargetActivity.class);
startActivity(intent);

- Khai báo không tường minh: cung cấp thao tác cần làm gì, với loại
dữ liệu nào, thao tác thuộc nhóm nào… hệ thống sẽ tìm activity
tương ứng để khởi động.

Ví dụ: Gọi Activity không tưởng minh

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivity(intent);

• Liên lạc giữa 2 Activity

Khi khởi động một activity, ta có thể gửi kèm dữ liệu trong intent như ví
dụ sau:
intent.putExtra("value1", new String("Hello"));
intent.putExtra(“value2", new Long(100));Bên phía activity
được khởi động, có thể lấy dữ liệu được gửi như sau:
getIntent().getExtras().getString("value1");
getIntent().getExtras().getLong("value2");
Có thể khởi động một activity với một yêu cầu nào đó và activity kia
khi làm xong công việc sẽ trả lại kết quả cho activity trước
Báo cáo môn Đồ án môn học chuyên ngành Trang 7


Ví dụ activity A yêu cầu một activity làm giúp việc chụp ảnh, activity B
đáp ứng được việc này, sau khi user chụp ảnh xong sẽ trả lại file ảnh
cho activity A.


Như thế sẽ đỡ tốn nhiều công sức làm một việc mà người khác đã làm
rồi.
1.3.2. Services
Service là một thành phần chạy nền, thực thi trong một thời gian dài.
Một service không cung cấp giao diện người dùng, mà chạy phía dưới,
không cần tương tác với người dùng. Một activity có thể khởi chạy một
dịch vụ và tương tác với chúng.
Một Service có thể được sử dụng theo 2 cách:

- Nó có thể được bắt đầu và được cho phép hoạt động cho đến khi một
người nào đó dừng nó lại hoặc nó tự ngắt. Ở chế độ này, nó được bắt
đầu bằng cách gọi Context.startService() và dừng bằng lệnh
Context.stopService(). Nó có thể tự ngắt bằng lệnh Service.stopSelf()
hoặc Service.stopSelfResult(). Chỉ cần một lệnh stopService() để ngừng
Service lại cho dù lệnh startService() được gọi ra bao nhiêu lần.

- Service có thể được vận hành theo như đã được lập trình việc sử dụng
một Interface mà nó định nghĩa. Các người dùng thiết lập một đường
truyền tới đối tượng Service và sử dụng đường kết nói đó để thâm nhập
vào Service. Kết nối này được thiết lập bằng cách gọi lệnh
Context.bindService() và được đóng lại bằng cách gọi lệnh
Context.unbindService(). Nhiều người dùng có thể kết nối tới cùng một
thiết bị. Nếu Service vẫn chưa được khởi chạy, lệnh bindService() có
thể tùy ý khởi chạy nó. Hai chế độ này thì không tách biệt toàn bộ. Bạn
có thể kết nối với một Service mà nó đã được bắt đầu với lệnh
startService(). Ví dụ, một Service nghe nhạc ở chế độ nền có thể được
bắt đầu bằng cách gọi lệnh startService() cùng với một đối tượng Intent
mà định dạng được âm nhạc để chơi. Chỉ sau đó, có thể là khi người sử
dụng muốn kiểm soát trình chơi nhạc hoặc biết thêm thông tin về bài hát

hiện tại đang chơi, thì sẽ có một Activity tạo lập một đường truyền tới
Service bằng cách gọi bindService(). Trong trường hợp như thế này,
Báo cáo môn Đồ án môn học chuyên ngành Trang 8

stopService() sẽ không thực sự ngừng Service cho đến khi liên kết cuối
cùng được đóng lại.

Giống như một Activity, một Service cũng có các phương thức chu kỳ
thời gian mà bạn có thể cài đặt để kiểm soát những sự thay đổi trong
trạng thái của nó. Những những phương thức của Service thì ít hơn là
của Activity – chỉ có 3- và chúng thì được sử dụng rộng rãi, không được
bảo vệ.
void onCreate()
void onStart(Intent intent)
void onDestroy()

Bằng việc thực hiện những phương thức này, bạn có thể giám sát 2 vòng
lặp của chu kỳ thời gian của mỗi Service.
Entire lifetime của một Service diễn ra giữa thời gian onCreate() được
gọi ra và thời gian mà onDestroy() trả lại. Giống như một Activity, một
Service lại tiết hành cài đặt ban đầu ở onCreate(), và giải phóng tát cả
các tài nguyên còn lại ở onDestroy() .

Ví dụ, một Service phát lại nhạc có thể tạo ra một luồng và bắt đầu chơi
nhạc onCreate(),và sau đó luồng chơi nhạc sẽ dừng lại ở onCreate(),
Active lifetime của một Service bắt đầu bằng một lệnh tới onStart().
Đâylà phương thức được chuyển giao đối tượng Intent mà đã được
thông qua để tới startService() Service âm nhạc sẽ mở đối tượng Intent
để quyết định xem sẽ chơi loại nhạc nào và bắt đầu phát nhạc.
Không có callback tương đương nào cho thời điểm Service ngừng lại –

không có phương thức onStop() .

Các phương thức onCreate() và onDestroy() được gọi cho tất cả các
Service dù chúng có được bắt đầu bằng Context.startService() hoặc
Context.bindService() hay không. Tuy nhiên thì, onStart() chỉ được gọi
ra đối với các Service bắt đầu bằng startService().
Nếu một Service cho phép những Service khác kết nối với nó thì sẽ có
thêm các phương thức callback dành cho Service đó để thực hiên

IBinder onBind(Intent intent)
boolean onUnbind(Intent intent)
void onRebind(Intent intent)

Báo cáo môn Đồ án môn học chuyên ngành Trang 9

Hàm callback onBind() thông qua đối tượng Intent đã đựoc truyền đến
bindService và onUnbind() được chuyển giao đối tượng mà đã được
chuyển đến. Nếu Service đang được chỉ định (binding), onBind() quay
trở lại kênh thông tin mà người dùng sử dụng để tương tác với Service.
Phương thức onUnbind() có thể yêu cầu onRebind() được gọi nếu một
người dùng kết nối với Service.

Biểu đồ dưới đây minh họa cho các phương thức callback giành cho
một Service. Mặc dù, nó phân tách các Service được tạo ra thông qua
startService với các Service mà được tạo ra bằng bindService(). Hãy
nhớ rằng bất kì Service nào, cho dù nó được khởi tạo như thế nào thì nó
vẫn có thể cho phép các người dùng kết nối tới nó một cách hiệu quả
nhất, cho nên bất kì Service nào cũng có thể được chỉ định thông qua
các các phương thức onBind()và onUnbind().
Báo cáo môn Đồ án môn học chuyên ngành Trang 10



Service LifeCycle
1.3.3. Content Provider
Content Provider quản lý việc chia sẻ dữ liệu. Dữ liệu được lưu trữ
trong cơ sở dữ liệu, thẻ nhớ, trên Web. Thông qua content provider,
những ứng dụng khác có thể truy cập được những dữ liệu này.
1.3.4. Broadcast Receiver
Boardcast Receiver là thành phần đáp ứng lại những thông báo từ phía
hệ thống. Ví dụ như những thông báo tắt màn hình, pin yếu, … Một ứng
dụng cũng có thể tạo ra Broadcast Receiver, ví dụ như để thông báo đã
download xong một file nào đó. Tóm lại, Broadcast Receiver là thành
Báo cáo môn Đồ án môn học chuyên ngành Trang 11

phần giúp phát ra một sự kiện nào đó tới toàn bộ hệ thống, và một ứng
dụng nào đó có thể nhận sự kiện này và xử lý tương ứng.
2. Kỹ thuật lập trình game trên Android.
Lập trình game về logic thì cũng giống như lập trình game trên các thiết bị khác.
Vấn đề ở đây là thiết bị di động Android có cấu hình khá thấp so với máy tính,
màn hình nhiều kích cỡ khác nhau, việc nhập liệu cũng không linh hoạt bằng. Vì
vậy lập trình game trên Android cũng đòi hỏi xử lý nhiều vấn đề phát sinh. Dưới
đây là một số kỹ thuật về lập trình game trên Android.
2.1. Thư viện đồ họa OpenGL

Như đã nói ở trên, thư viện đồ họa OpenGL là một thư viện đồ họa 3D, hỗ
trợ tương tác trực tiếp với phần cứng, nhất là với bộ tăng tốc đồ họa. Sử
dụng thư viện đồ họa này, người dùng có thể tạo ra nhưng game có những
hiệu ứng phức tạp, chất lượng hình ảnh cao, mà vẫn giữ được sử mượt mà
cho game.
OpengGL là một giao diện phần mềm độc lập với phần cứng (hardware –

independent software interface) hộ trợ cho lập trình đồ họa. Để làm được
điều này, OpenGL không thực hiện các tác vụ thuộc về hệ điều hành cũng
như không nhận dữ liệu nhập của người dùng (người dùng giao tiếp với
OpenGL thông qua OpenGL API). Nó là lớp trung gian giữa người dùng và
phần cứng. Nghĩa là nó giao tiếp trực tiếp với driver của thiết bị đồ họa.
Trong bộ NDK của Android đã tích hợp sẵn OpenGL ES, nên ta chỉ việc
include khi cần dùng đến những API của OpenGL.
OpenGL vốn là một thư viện đồ họa 3D. Nhưng ta cũng có thể dùng nó để
vẽ hình ảnh 2D.
2.1.1. Khởi tạo OpenGL
Báo cáo môn Đồ án môn học chuyên ngành Trang 12

Để tương tác được với OpenGL, trước tiên ta phải khởi tạo thiết bị sử
dụng OpenGL. Để khởi tạo, bên phía Java, ta tạo ra một lớp
GL2JNIView thừa kế từ lớp GLSurfaceView. GLSurfaceView là một
lớp được thừa kế từ lớp View, có tác dụng hiển thị hình ảnh được vẽ từ
OpenGL.
Trong hàm khởi tạo Activity, ta set view cho Activity là đối tượng
GL2JNIView.
mView = new GL2JNIView(getApplication(), 320, 480);
setContentView(mView);
Tiếp theo, ta gọi một số hàm cài đặt phép chiếu của OpenGL, để chuyển
từ môi trường 2D sang 3D. Để tạo được hình ảnh 2D, ta sử dụng phép
chiếu song song. Trong hình bên dưới, bên trái là phép chiếu phối cảnh,
sẽ cho ta hình ảnh 3D, với cảm giác xa gần. Còn hình bên phải là phép
chiếu song song, sẽ loại bỏ cảm giác xa gần, cho ta hình ảnh 2D.
Để tạo được hình ảnh này, ta dùng hàm
glOrthof(0.0f, width, height, 0.f, -100.0f, 100.0f);




Tiếp theo, ta sẽ cấu hình một số thuộc tính, enable một số chức năng
như VertexArray (buffer chứa các đỉnh), TexureCoordinateArray (mảng
chứa tọa độ texture), chức năng vẽ với kênh trong suốt alpha (Blend).
Ngoài ra ta cũng disable một số chức năng không cần thiết trong vẽ hình
2D như CullFace (loại bỏ hình ảnh dựa vào chiều của các vertex,
thường sử dụng trong 3D).
Báo cáo môn Đồ án môn học chuyên ngành Trang 13

2.1.2. Texture
Texture là lớp vật liệu để phủ lên bề mặt 3D. Nhưng ở đây khi ta vẽ
hình ảnh 2D, thì texture chính là những hình ảnh cần vẽ. Để load được
texture, chúng ta cần phải có một ImageData, là một mảng byte màu.
Mảng này được đọc ra từ file ảnh, trong trường hợp này là file PNG.
Sau khi khởi tạo texture, ta sẽ đưa mảng byte này gắn với texture đó.
2.1.3. Vẽ texture
Để vẽ được texture lên, ta cần phủ texture này lên một mảng đỉnh. Mảng
đỉnh này tạo ra một hình có dạng hình chữ nhật, với kích thước bằng
kích thước ta muốn vẽ lên màn hình. Sau đó, khi muốn vẽ phần nào của
texture lên màn hình, ta gán toạ độ tương ứng cho hình vẽ.
2.2. Thư viện âm thanh OpenAL

Thư viện âm thanh OpenAL giúp cho việc chơi âm thanh hiệu quả hơn.
Thư viện này giúp tương tác trực tiếp với phần cứng âm thanh, đặc biệt có
khả năng tạo ra âm thanh vòm, làm cho game trở nên trung thực hơn.
(0.0f, 0.0f)
(1.0f, 0.0f)
(1.0f, 0.0f)
(1.0f,1.0f)
Báo cáo môn Đồ án môn học chuyên ngành Trang 14


Các hàm chức năng chính của OpenAL được đóng gói trong source object,
audio buffer và single listener. Source object chứa con trỏ tới buffer, vận
tốc, vị trí và hướng của âm thanh. Listener object cũng tương tự source
object, nhưng là đối tượng người nghe. Buffer chứa dữ liệu âm thanh, định
dạng PCM. Renderring engine cần thiết cho việc tính toán khoảng cách, tạo
hiệu ứng Doppler…
Trong NDK đã tích hợp các file header và thư viện OpenAL.
2.2.1. Khởi tạo OpenAL
Để khởi tạo OpenAL, ta cần khởi tạo context cho device đó.
_mContext = alcCreateContext(_mDevice, contextAttribs);
alcMakeContextCurrent(_mContext);
Hàm alcCreateContext sẽ tạo ra context cho thiết bị, trong đó _mDevice
là id của thiết bị âm thanh. Thông thường điện thoại Android chỉ có một
chip xử lý âm thanh. Do đó ta gán _mDevice = 0.
Hàm alcMakeContextCurrent sẽ gán context vừa tạo thành context hiện
tại.
2.2.2. Tạo đối tượng Audio
Để tạo được đối tượng Audio, ta cần có audio data. Audio data sẽ được
load từ file
Trước tiên ta load dữ liệu vào buffer:
alGenBuffers(1, &bufferID);
alBufferData(bufferID, format, auData, auDataSize,
samplesPerSec);
Sau đó ta tạo ra một source và gắn buffer vừa tạo vào source này.
alGenSources(1, &sourceID);
alSourcei(sourceID, AL_BUFFER, bufferID);
2.2.3. Chơi âm thanh.
Trước khi chơi âm thanh, ta phải chỉ ra rằng ta đang sử dụng source đó.
Sau đó gọi hàm chơi âm thanh.

if (isLoop) {
alSourcei(sourceID, AL_LOOPING, AL_TRUE);
Báo cáo môn Đồ án môn học chuyên ngành Trang 15

} else {
alSourcei(sourceID, AL_LOOPING, AL_FALSE);
}
alSourcePlay(sourceID);
Tương tự cho là các hàm tạm dừng và dừng âm thanh.
2.3. NDK
NDK là một tập hợp các công cụ cho phép nhúng code C/C++ vào ứng
dụng Android. Code C/C++ sẽ được biên dịch ra thành những thư viện
Linux. Những đoạn code viết bằng C/C++ sẽ được chạy trực tiếp không qua
máy ảo Dalvik, do đó làm tăng tốc độ thực thi của chương trình. Bên cạnh
đó, có nhiều thư viện được viết bằng C/C++, do đó có thể sử dụng được
những thư viện này ngay trên Android.
NDK cung cấp một số hỗ trợ sau:
o Một tập hợp các Toos và files build dùng để tạo ra các thư viện mã từ
sources C và C++.
o Cách để nhúng các thư viện mã vào một file (.apk) gói ứng dụng mà chúng
ta có thể chạy được trên các thiết bị android.
o Tài liệu, ví dụ và một số hướng dẫn.
o Một bộ các thư viện C/C++ được hỗ trợ trong tất cả các phiên bản sau này
của hệ điều hành Android, bắt đầu từ Android 1.5. Từ phiên bản 2.3 trở đi,
hệ điều hành android còn hỗ trợ them cách viết Activity bằng C/C++.
Khi nào thì dùng native code?
Không phải khi nào NDK cũng đều có lợi với tất cả các ứng dụng. Vì vậy
chúng ta cần cân bằng lợi ích với nhược điểm của nó. Đặc biệt trong trường
hợp sử dụng native code không làm tăng hiệu suất thực thi mà làm tăng sự
phức tạp của ứng dụng. Nói chung chỉ nên sử dụng native lập trình nếu nó là

cần thiết đối với ứng dụng của mình không nên vì chúng ta thích chương trình
trong C/C++.
- Framework Android cung cấp 2 cách để dùng native code : Dùng Android
framework để viết ứng dụng của mình và dùng JNI để truy cập API được cung
cấp bởi Android NDK. Kỹ thuật này cho phép chúng ta tận dụng các tiện ích
của Android Framework, nhưng vẫn cho phép chúng ta viết native code khi
cần thiết. Chúng ta có thể cài ứng dụng sử dụng Native code thông qua JNI
trên thiết bị chạy android 1.5 hoặc mới hơn.
Báo cáo môn Đồ án môn học chuyên ngành Trang 16

- Viết một native activity, cho phép chúng ta thực hiện cài đặt vòng đời của
ứng dụng android trên native code. Android SDK cung cấp lớp NativeActivity
cho phép chúng ta cài đặt vòng đời thông qua các hàm sau (onCreate(),
onResume(), ).
- Development tool NDK gồm một bộ công cụ (compilers, linkers, ) dùng để
tạo ra mã nhị phân cho bộ vi xử lý ARM trên hệ điều hành Linux, OS X, và
Windows(với Cygwin). Cung cấp một bộ headers của hệ thống cho các API
native chuẩn mà được đảm bảo được hỗ trợ trong tất cả các phiên bản sau này
của nền tảng:
 OpenGL ES 1.1 và OpenGL ES 2.0(thư viện graphics library) headers.
 Libjnigraphics (Pixel buffer access) header(for Android 2.2. trở lên).
 Thư viện OpenSL ES native audio.
 API cho ứng dụng android.
NDK cũng cung cấp một hệ thống biên dịch giúp chúng ta làm việc hiệu quả với
mã nguồn của mình mà không cần điều khiển chi tiết các công cụ/ nền tảng/ CPU/
ABI. Người dùng chỉ cần tạo các file biên dịch đơn giản để mô tả mã nguồn của
mình mà trong ứng dụng Android sử dụng. Và hệ thống biên dịch sẽ sử dụng các
file này để biên dịch, và tạo ra một thư viện động bỏ trực tiếp vào trong dự án của
mình.
H thng và phn mm yêu cu:

- Hoàn tất cài đặt một Android SDK (bao gồm tất cả các phụ thuộc).
- Phiên bản SDK Android 1.5 trở đi.
- Hệ điều hành hỗ trợ : Window XP (32-bit) hoặc vista (32- hoặc 64 -bit), Mac Os
x10.4.8 hoặc hơn (đối với X86), Linux (32 hoặc 64 bit, thử nghiệm trên Linux
Ubuntu Dapper Drake).
- Các công cụ Cần Thiết:
+ Đối với tất cả các nền tảng, bắt buộc GNU Make 3.81 trở lên.
+ Đối với Window, bắt buộc Cygwin 1.7 trở lên. NDK không làm việc với
Cygwin 1.5.
- Nền tảng Android tương thích.
Báo cáo môn Đồ án môn học chuyên ngành Trang 17

Các thư viện native được tạo ra bởi Android NDK chỉ có thể sử dụng trên các thiết
bị Android phiên bản 1.5 trở đi. Điều này là do Bộ công cụ và ABI liên quan đến
những thay đổi làm cho các thư viện native không tương thích với hình ảnh hệ
thống 1.0 và 1.1. Vì lí do này nên chúng ta nên sử dụng thư viện native được tạo ra
với NDK trong ứng dụng mà được triển khai trên các thiết bị chạy trên nền tảng
android 1.5 trở đi.
Để đảm bảo tính tương thích, một ứng dụng dùng thư viện native tạo ra với NDK
phải khai báo <uses- sdk> phần tử trong file mainfese của nó, với một giá trị thuộc
tính của android:minSdkVersion 3 hoặc lớn hơn.
Ví dụ:
<manifest>
<uses-sdk android:minSdkVersion="3" />
</manifest>

- Hoạt động của JNI và quy trình biên dịch như chúng ta đều biết, ứng dụng
android chạy trên nền chính là Java. Muốn chạy C/C++ ta có hai giải pháp:
+ Sử dụng JNI: từ android 1.5 trở về sau.
+ Sử dụng Native Activity: từ android 2.3 trở về sau. Native Activity là phương án

lựa chọn tốt hơn, bởi vì chương trình sẽ không tốn chi phí giao dịch giữa máy ảo
Java và C/C++. Tuy nhiên, tới thời điểm hiện tại, số lượng các thiết bị hổ trợ
Android 2.3 tương đối hiếm nên chúng ta sẽ sử dụng giải pháp JNI.
- Hoạt động của JNI được mô tả như sau:
+ Các phương thức JNI được đánh dấu bằng từ khóa native.
+ Các phương thức này được viết bằng C++ và biên dịch ra thư viện liên kết động
.so.
+ Thư viện liên kết động được Load lên trong chương trình Java bằng lời gọi
System.loadLibrary( );
+ Khi trong chương trình Java có lời gọi tới hàm native, máy ảo Java sẽ tìm kiếm
trong thư viện động xem hàm này đã được cài đặt chưa, sau đó các đối tượng Java
sẽ được chuyển thành C++ để thực hiện lời gọi tới C++.
Báo cáo môn Đồ án môn học chuyên ngành Trang 18

+ Trong C++ cũng cung cấp các thư viện cho phép giao tiếp tới máy ảo và chương
trình Java.

- Khai báo phương thức native ở trong lớp Java.
- Khai báo và cài đặt phương thức này trong C. (Nếu C++ thì phải sử dụng extern
“C” để tránh sửa tên trong C++). Quy tắc đặt tên hàm đó như sau:
<tengoi_tenlop_tenphuongthuc>
Sau đó dùng NDK để biên dịch mã nguồn C thành thư viện liên kết động và thư
viện này được tự động bỏ vào thư mục lib của dự án android. Viết chương trình
java gọi các hàm native này. Dùng bộ SDK để biên dịch thành ứng dụng apk.
- Do các bước sử dụng NDK để biên dịch được thực hiện trên dấu nhắc lệnh, do
đó chúng ta sẽ tạo tập tin lệnh để thực hiện điều này.
2.4. Lưu trữ thông tin.


Thông tin trong game trên Android có thể được lưu trữ trên SQLite hoặc trên

thẻ nhớ. Lưu trữ trên database sẽ có tính bảo mật cao hơn, chặt chẽ hơn. Còn lưu
trữ trên thẻ nhớ sẽ dễ backup hơn, dễ chuyển sang các thiết bị khác hơn.
Ngoài hai cách lưu trữ thông tin như trên, Android còn cung cấp cách lưu trữ
thông tin thông qua đối tượng SharedReference. Thông tin lưu qua đối tượng này
sẽ được lưu tại thư mục của ứng dụng, nằm trong bộ nhớ trong của máy.
 d liu bng SQLite:
Trong Android , cơ sở dữ liệu mà bạn tạo cho 1 ứng dụng thì chỉ ứng dụng đó có
quyền truy cập và sử dụng, các ứng dụng khác thì không. Khi đã được tạo, cơ sở
dữ liệu SQLite được chứa trong thư mục /data/data/<package_name>/databases.
Báo cáo môn Đồ án môn học chuyên ngành Trang 19

c thc hin vi CSDL:
1. Tạo 1 CSDL (thông thường chỉ cần làm 1 lần)
2. Mở CSDL đó
3. Thêm giá trị vào trong table
4. Truy vấn.
5. Đóng CSDL

1. T d liu
Đầu tiên add 1 class DBAdapter để xử lý tất cả các thao tác liên quan đến
CSDL.
public static final String KEY_ID = "_id";
public static final String KEY_NAME = "name";

private DatabaseHelper mDbHelper;
private SQLiteDatabase mDB;

private static final String DATABASE_CREATE = "create table users (_id integer
primary key autoincrement, "
+ "name text not null);";

private static final String DATABASE_NAME = "Database_Demo";
private static final String DATABASE_TABLE = "users";
private static final int DATABASE_VERSION = 2;

private final Context mContext;
Tạo 1 lớp bên trong DBAdapter được extend từ lớp SQLiteOpenHelper, override 2
phương thức onCreate() và onUpgrade() để quản lý việc tạo CSDL và version của
CSDL đó.

private static class DatabaseHelper extends SQLiteOpenHelper{
public DatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
Báo cáo môn Đồ án môn học chuyên ngành Trang 20

super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.i(TAG, "Upgrading DB");
db.execSQL("DROP TABLE IF EXISTS users");
onCreate(db);
}
}

2. M CSDL

public DBAdapter open()
{
mDbHelper = new DatabaseHelper(mContext, DATABASE_NAME, null,
DATABASE_VERSION);
mDB = mDbHelper.getWritableDatabase();
return this;
}
3. Thêm giá tr vào CSDL

public long createUser(String name){
Báo cáo môn Đồ án môn học chuyên ngành Trang 21

ContentValues inititalValues = new ContentValues();
inititalValues.put(KEY_NAME, name);
return mDB.insert(DATABASE_TABLE, null, inititalValues);
}
4. Truy vn
Ta có thể get toàn bộ data hoặc có thể get data theo ID ( tiện cho việc chỉnh sửa
hay cập nhật thông tin của từng bản ghi).

public Cursor getAllUsers(){
return mDB.query(DATABASE_TABLE, new String[] {KEY_ID, KEY_NAME}, null,
null, null, null, null);
}
Còn rất nhiều các thao tác như sửa, xóa, update bản ghi, tất cả các chức năng đó
đều được cung cấp bởi lớp SQLiteDatabase, ta chỉ cần cụ thể hóa bằng các câu
truy vấn là được.




public void close(){
mDbHelper.close();
}
6. S dng CSDL

Để test CSDL mà bạn vừa tạo, ta có thể thêm 1 vài dòng code để thêm 1 user và
hiển thị CSDL lên màn hình thông qua lớp Activity ban đầu:
Ví dụ ở đây ta tạo mới 1 user thông qua câu lệnh mDB.createUser("Username");
sau đó

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Báo cáo môn Đồ án môn học chuyên ngành Trang 22

setContentView(R.layout.main);
mDB = new DBAdapter(this);
mDB.open();
mDB.createUser("Do Minh Thong");
getData();
}
private void getData(){
mCursor = mDB.getAllUsers();
startManagingCursor(mCursor);
String[] from = new String[]{DBAdapter.KEY_NAME};
int[] to = new int[] {R.id.text1};
SimpleCursorAdapter users = new SimpleCursorAdapter(this,
R.layout.users_row, mCursor, from, to);
setListAdapter(users);

}

2.5. Các thư viện khác.
- libzip : đọc file zip, giúp đọc dữ liệu từ file apk.
- libpng : đọc file png thành dữ liệu thô của hình ảnh.
2.6. Vòng đời của một game.
Như chúng ta đã biết, game là một chu trình khép kín, lặp đi lặp lại. Ban
đầu là nhận sự kiện input. Sau đó xử lý tương ứng trong hàm Update(), cuối
cùng là vẽ nó lên màn hình thông qua hàm Render().
Game trên Android cũng có cấu trúc tương tự. Nó cũng bao gồm những
hàm xử lý input, update, render, nhưng được gọi tự động.

×