ANDROID NÂNG CAO
Bài 2:

Background Processing
Nội dung bài học
●

Thread.

●

Shared Agenda.

●

AsyncTask.

●

Loader.
Thread
●
●

●

Thread là một đơn vị thực thi đồng thời.
Thông thường chúng ta sử dụng Thread trong
tình huống có một công ...
Shared Agenda
●

Trong Android, việc xử lý tuần tự các message
và task được thực hiện thông qua Shared
Agenda Thread patte...
Shared Agenda
●

Shared Agenda (SA):
●
●

●

Một thread có queue chứa các message & task.
Message (android.os.Message) là ...
Shared Agenda
●

Looper (android.os.Looper):
●

●

Looper được dùng để biến một thread thành SA với
một message queue.

Ha...
Handler
●

●

Handler được dùng để schedule message
(Message) và task (Runnable).
Để gửi một task vào queue ta dùng các ph...
Handler
●

Để gửi một message vào queue ta dùng các
phương thức sau:
●

sendEmptyMessage(int)

●

sendMessage(Message)

●
...
Looper
●

Looper quản lý message queue cho thread.

●

Looper.prepare() dùng để tạo ra message queue.

●

Looper.loop() dù...
Sample Code
Handler mhandler = null;
public run(){
try{
//Biến thread thành shared agenda
Looper.prepare();
//Bind Handler...
UI Thread
●

Trong mỗi ứng dụng Android có một thread đặc
biệt gọi là UI Thread:
●

UI Thread tự động start khi chương trì...
Bài tập 04
Hiện thực chương trình Android có các chức năng
sau đây:
●

Đọc dữ liệu từ một tập tin ở SD card.

●

Hiển thị ...
AsyncTask
●

●

AsyncTask là phương tiện khác để xử lý công
việc sử dụng background thread và giao tiếp với
UI thread mà k...
AsyncTask
●

Sơ đồ trạng thái:
Ví dụ
Hiện thực chương trình Android có các chức năng
sau đây sử dụng kỹ thuật AsyncTask:
●

●
●

Background thread đếm từ...
Ví dụ
public class AsyncTaskSample extends Activity {
private TextView txtCounter;
@Override
public void onCreate(Bundle s...
Ví dụ
class CounterAsyncTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected void onPreExecute() {
//Hiể...
Ví dụ
class CounterAsyncTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected void onPreExecute() {
//Hiể...
Ví dụ
@Override
protected void onPostExecute(Boolean result) {
if (result) {
txtCounter.setText("Kết thúc");
} else {
txtC...
Loader
●

●

●

●

●

Loader cung cấp một cơ chế load dữ liệu một cách
bất đồng bộ.
Giám sát nguồn cung cấp dữ liệu, mỗi k...
Loader API
Tên Class

Mô tả

LoaderManager

Là lớp trừu tượng dùng để quản lý các loader instance gắn với
Activity hay Fra...
Sử dụng Loader
●

Các bước để sử dụng Loader trong ứng dụng
Android:
●

Hiện thực một Activity hay Fragment.

●

Get một i...
Loader Example
public class LoadersSampleActivity extends ListActivity implements LoaderCallbacks<Cursor>
{
private Simple...
Loader Example
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri baseUri = Uri.parse("content://sm...
Nguyen Huu Phuoc, MEng.
●

 Blog:http://folami.nghelong.com

●

 Website http://phuocnh.nghelong.com
Upcoming SlideShare
Loading in...5
×

Android Nâng cao-Bài 2: Background Processing

2,787

Published on

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,787
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "Android Nâng cao-Bài 2: Background Processing"

  1. 1. ANDROID NÂNG CAO Bài 2: Background Processing
  2. 2. Nội dung bài học ● Thread. ● Shared Agenda. ● AsyncTask. ● Loader.
  3. 3. Thread ● ● ● Thread là một đơn vị thực thi đồng thời. Thông thường chúng ta sử dụng Thread trong tình huống có một công việc xử lý với khối lượng lớn hay thời gian thực hiện kéo dài. Có hai cách để tạo thread: ● ● ● Kế thừa lớp Thread và override phương thức run(). Tạo đối tượng Runnable và hiện thực phương thức run(). Để thực thi một thread gọi phương thức start()
  4. 4. Shared Agenda ● Trong Android, việc xử lý tuần tự các message và task được thực hiện thông qua Shared Agenda Thread pattern. ● ● ● Agenda là thuật ngữ trong ngành trí tuệ nhân tạo và thường được dùng trong AI Robotic. Pipline (xử lý ống) là thuật ngữ tương tự trong Hệ điều hành. Thuật ngữ này thường được sử dụng trong lĩnh vực xử lý đồng thời. Ý tưởng chính là dùng Shared Agenda thread để gửi message & task một cách tuần tự từ background thread đến UI thread và ngược lại.
  5. 5. Shared Agenda ● Shared Agenda (SA): ● ● ● Một thread có queue chứa các message & task. Message (android.os.Message) là một cấu trúc dữ liệu dùng trao đổi, xử lý. Task (java.lang.Runnable) là một đơn vị CPU có thể thực thi được. ● Nếu trong queue của SA không có task thì SA block. ● Các thread khác có thể gửi message đến SA. ● Nếu trong queue của SA có message thì các message này sẽ được xử lý tuần tự.
  6. 6. Shared Agenda ● Looper (android.os.Looper): ● ● Looper được dùng để biến một thread thành SA với một message queue. Handler (android.os.Handler): ● Handler: Là kênh để các thread khác gửi message đến SA. Thread Thread Looper Message Queue Handler Message
  7. 7. Handler ● ● Handler được dùng để schedule message (Message) và task (Runnable). Để gửi một task vào queue ta dùng các phương thức sau: ● ● postAtTime(Runnable, long) ● ● post (Runnable) postDelayed(Runnable,long) Các task đang nằm trong queue sẽ được thực thi ngay khi chúng được nhận.
  8. 8. Handler ● Để gửi một message vào queue ta dùng các phương thức sau: ● sendEmptyMessage(int) ● sendMessage(Message) ● sendMessageAtTime(Message,long) ● sendDelayedMessage(Message,long)
  9. 9. Looper ● Looper quản lý message queue cho thread. ● Looper.prepare() dùng để tạo ra message queue. ● Looper.loop() dùng để xử lý các message khi Thread đang thực thi.
  10. 10. Sample Code Handler mhandler = null; public run(){ try{ //Biến thread thành shared agenda Looper.prepare(); //Bind Handler mhandler = new Handler(){ //Bind vào thread hiện tại public void handleMessage(Message msg) { // xử lý message nhận được } } //Start looper Looper.loop(); }catch(Throwable ex){ //xử lý ngoại lệ } } //Ở một thread khác có thể truy xuất mhandler //Thì từ thread này có thể gửi message và task mhandler.post(new Runnable(){ @Override public void run(){ //Thực thi nghiệp vụ } });
  11. 11. UI Thread ● Trong mỗi ứng dụng Android có một thread đặc biệt gọi là UI Thread: ● UI Thread tự động start khi chương trình start. ● UI Thread nhận các sự kiện của người dùng. ● UI thread là một shared agenda. ● Để đăng ký Handler cho Looper của UI Thread sử dụng: Handler mHandler = new Handler(Looper.getMainLooper()) ● Lưu ý: ● Không block UI Thread (ANR) ● Không thay đổi các thành phần của UI bên ngoài thread UI. ● Sử dụng các phương pháp đồng bộ thread khi dùng chung dữ liệu
  12. 12. Bài tập 04 Hiện thực chương trình Android có các chức năng sau đây: ● Đọc dữ liệu từ một tập tin ở SD card. ● Hiển thị progress bar khi đang đọc dữ liệu. ● Trình bày nội dung tập tin lên TextView khi đọc xong dữ liệu. Yêu cầu: Sử dụng background thread để đọc dữ liệu và dùng Handler để giao tiếp với UI thread.
  13. 13. AsyncTask ● ● AsyncTask là phương tiện khác để xử lý công việc sử dụng background thread và giao tiếp với UI thread mà không dùng Thread hay Handler. Để sử dụng AsynTask, định nghĩa lớp con: class MyAsyncTask extends AsyncTask<Params, Progress, Result>{ @Override protected Result doInBackground(Params... params) {     return null; } } ● Params → Tham số của doInBackground (Array) ● Progress → Tham số của onProgressUpdate ● Result → Tham số của onPostExecute và giá trị trả về của doInBackground
  14. 14. AsyncTask ● Sơ đồ trạng thái:
  15. 15. Ví dụ Hiện thực chương trình Android có các chức năng sau đây sử dụng kỹ thuật AsyncTask: ● ● ● Background thread đếm từ 0 → 10. Cập nhật kết quả lên màn hình (UI Thread). Khi đến 10 thì hiển thị “Kết thúc”. Trong khi đếm thì hiển thị “busy indicator” ở thanh tiêu đề.
  16. 16. Ví dụ public class AsyncTaskSample extends Activity { private TextView txtCounter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Cài đặt chế độ hiển thị busy indicator ở thanh tiêu đề //Dòng lệnh này phải được gọi trước câu lệnh setContentView. requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.main); this.txtCounter = (TextView) findViewById(R.id.TextView01); this.txtCounter.setText("" + 0); //Gọi thực thi AsyncTask new CounterAsyncTask().execute("args as doInBackground"); }
  17. 17. Ví dụ class CounterAsyncTask extends AsyncTask<String, Integer, Boolean> { @Override protected void onPreExecute() { //Hiển thị busy indicator setProgressBarIndeterminateVisibility(true); } @Override protected Boolean doInBackground(String... params) { Log.v("AIT", "param:" + params[0]); for (int i = 0; i <= 10; i++) { try { //Gửi thông tin lên UI Thread publishProgress(i); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); return false; } } return true; }
  18. 18. Ví dụ class CounterAsyncTask extends AsyncTask<String, Integer, Boolean> { @Override protected void onPreExecute() { //Hiển thị busy indicator setProgressBarIndeterminateVisibility(true); } @Override protected Boolean doInBackground(String... params) { Log.v("AIT", "param:" + params[0]); for (int i = 0; i <= 10; i++) { try { //Gửi thông tin lên UI Thread publishProgress(i); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); return false; } } return true; }
  19. 19. Ví dụ @Override protected void onPostExecute(Boolean result) { if (result) { txtCounter.setText("Kết thúc"); } else { txtCounter.setText("Lỗi"); } //Ẩn busy indicator setProgressBarIndeterminateVisibility(false); } @Override protected void onProgressUpdate(Integer... values) { txtCounter.setText("" + values[0]); } } }
  20. 20. Loader ● ● ● ● ● Loader cung cấp một cơ chế load dữ liệu một cách bất đồng bộ. Giám sát nguồn cung cấp dữ liệu, mỗi khi nguồn cung cấp dữ liệu có sự thay đổi thì nó tự động cập nhật dữ liệu ở kết quả. Mỗi Activity hay Fragment đều có Loader. Mỗi khi được tạo lại do cấu hình hệ thống thay đổi thì nó tự động khôi phục lại đúng điểm mà loader trước đó đang giữ và do đó không truy vấn lại dữ liệu. Loader có từ API 11+ (sử dụng support library cho phiên bản cũ).
  21. 21. Loader API Tên Class Mô tả LoaderManager Là lớp trừu tượng dùng để quản lý các loader instance gắn với Activity hay Fragment. Loader Là lớp trừu tượng dùng để load dữ liệu bất đồng bộ, giám sát sự thay đổi của nguồn cung cấp dữ liệu để cập nhật dữ liệu kết quả. Các lớp thừa kế là AsyncTaskLoader. AsyncTaskLoader Là lớp trừu tượng, cung cấp một AsyncTask để thực hiện một công việc chiếm thời gian dài hay load dữ liệu lớn. Lớp thừa kế là CursorLoader CursorLoader Là lớp con của AsyncTaskLoader, là cơ chế tốt nhất để load data từ provider. LoaderManager.LoaderCallbacks Để tương tác với LoaderManager, client cần hiện thực các callback sau đây: ●onCreateLoader → Tạo mới loader từ ID được cung cấp. ●onLoadFinished → Gọi khi loader đã hoàn thành xong nhiệm vụ. ●onLoaderReset → Gọi khi loader bị reset.
  22. 22. Sử dụng Loader ● Các bước để sử dụng Loader trong ứng dụng Android: ● Hiện thực một Activity hay Fragment. ● Get một instance của LoaderManager. ● ● ● Sử dụng CursorLoader (hoặc hiện thực một custom loader). Hiện thực các callbacks trong LoaderManager.Callbacks. Sử dụng dữ liệu từ loader để trình bày lên GUI.
  23. 23. Loader Example public class LoadersSampleActivity extends ListActivity implements LoaderCallbacks<Cursor> { private SimpleCursorAdapter mAdapter = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Tạo adapter rỗng dùng để trình bày dữ liệu chúng ta load được lên ListView. mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, new String[] { "address", "body" }, new int[] { android.R.id.text1, android.R.id.text2 }, 0); setListAdapter(mAdapter); //Khởi tạo Loader với ID = 0 getLoaderManager().initLoader(0, null, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { // TODO Auto-generated method stub } @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { // TODO Auto-generated method stub } @Override public void onLoaderReset(Loader<Cursor> arg0) { // TODO Auto-generated method stub } }
  24. 24. Loader Example @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Uri baseUri = Uri.parse("content://sms"); // Tạo ra trả về đối tượng CursorLoader. return new CursorLoader(this, baseUri, null, null, null,null); } @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { //Điền dữ liệu từ Cursor sang mAdapter mAdapter.swapCursor(arg1); } @Override public void onLoaderReset(Loader<Cursor> arg0) { //Reset adapter mAdapter.swapCursor(null); }
  25. 25. Nguyen Huu Phuoc, MEng. ●  Blog:http://folami.nghelong.com ●  Website http://phuocnh.nghelong.com

×