• Like
  • Save
Android Nâng cao-Bài 2: Background Processing
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

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

  • 1,599 views
Published

 

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,599
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
0
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. ANDROID NÂNG CAO Bài 2: Background Processing
  • 2. Nội dung bài học ● Thread. ● Shared Agenda. ● AsyncTask. ● Loader.
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. AsyncTask ● Sơ đồ trạng thái:
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Nguyen Huu Phuoc, MEng. ●  Blog:http://folami.nghelong.com ●  Website http://phuocnh.nghelong.com