Đây là tài liệu bài 2 trong bộ 9 bài lập trình android nâng cao. Bài này mô tả các kỹ năng xử lý công việc dưới background của một chương trình Android như async task, loader, đa luồng (multithreading)…
ANDROID NÂNG CAO Bài 2: Background Processing Nội dung học ● Thread ● Shared Agenda ● AsyncTask ● Loader Thread ● ● ● Thread đơn vị thực thi đồng thời Thông thường sử dụng Thread tình có công việc xử lý với khối lượng lớn hay thời gian thực kéo dài Có hai cách để tạo thread: ● ● ● Kế thừa lớp Thread override phương thức run() Tạo đối tượng Runnable thực phương thức run() Để thực thi thread gọi phương thức start() Shared Agenda ● Trong Android, việc xử lý message task thực thông qua Shared Agenda Thread pattern ● ● ● Agenda thuật ngữ ngành trí tuệ nhân tạo thường dùng AI Robotic Pipline (xử lý ống) thuật ngữ tương tự Hệ điều hành Thuật ngữ thường sử dụng lĩnh vực xử lý đồng thời Ý tưởng dùng Shared Agenda thread để gửi message & task cách từ background thread đến UI thread ngược lại Shared Agenda ● Shared Agenda (SA): ● ● ● Một thread có queue chứa message & task Message (android.os.Message) cấu trúc liệu dùng trao đổi, xử lý Task (java.lang.Runnable) đơn vị CPU thực thi ● Nếu queue SA task SA block ● Các thread khác gửi message đến SA ● Nếu queue SA có message message xử lý Shared Agenda ● Looper (android.os.Looper): ● ● Looper dùng để biến thread thành SA với message queue Handler (android.os.Handler): ● Handler: Là kênh để thread khác gửi message đến SA Thread Thread Looper Message Queue Handler Message Handler ● ● ● Handler dùng để schedule message (Message) task (Runnable) Để gửi task vào queue ta dùng phương thức sau: ● post (Runnable) ● postAtTime(Runnable, long) ● postDelayed(Runnable,long) Các task nằm queue thực thi chúng nhận Handler ● Để gửi message vào queue ta dùng phương thức sau: ● sendEmptyMessage(int) ● sendMessage(Message) ● sendMessageAtTime(Message,long) ● sendDelayedMessage(Message,long) Looper ● Looper quản lý message queue cho thread ● Looper.prepare() dùng để tạo message queue ● Looper.loop() dùng để xử lý message Thread thực thi 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 public void handleMessage(Message msg) { // xử lý message nhận } } //Start looper Looper.loop(); }catch(Throwable ex){ //xử lý ngoại lệ } } //Ở thread khác truy xuất mhandler //Thì từ thread gửi message task mhandler.post(new Runnable(){ @Override public void run(){ //Thực thi nghiệp vụ } }); Bài tập 04 Hiện thực chương trình Android có chức sau đây: ● Đọc liệu từ tập tin SD card ● Hiển thị progress bar đọc liệu ● Trình bày nội dung tập tin lên TextView đọc xong liệu Yêu cầu: Sử dụng background thread để đọc liệu dùng Handler để giao tiếp với UI thread AsyncTask ● ● AsyncTask phương tiện khác để xử lý công việc sử dụng background thread 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{ @Override protected Result doInBackground(Params params) { return null; } } ● Params → Tham số doInBackground (Array) ● Progress → Tham số onProgressUpdate ● Result → Tham số onPostExecute giá trị trả doInBackground AsyncTask ● Sơ đồ trạng thái: Ví dụ Hiện thực chương trình Android có chức sau sử dụng kỹ thuật AsyncTask: ● ● ● Background thread đếm từ → 10 Cập nhật kết lên hình (UI Thread) Khi đến 10 hiển thị “Kết thúc” Trong đếm hiển thị “busy indicator” tiêu đề 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 tiêu đề //Dòng lệnh phải 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"); } Ví dụ class CounterAsyncTask extends AsyncTask { @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 [...]... @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 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ừ 0 → 10... 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... 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 AsyncTask ● ● AsyncTask là phương tiện khác để xử lý công việc sử dụng background thread và giao tiếp... setProgressBarIndeterminateVisibility(false); } @Override protected void onProgressUpdate(Integer values) { txtCounter.setText("" + values[0]); } } } Bài tập 05 Hiện thực chương trình Android có các chức năng sau đây: Chúng ta có 1 list khoảng 20 loại hoa, thông tin mỗi loài hoa bao gồm 1 bức ảnh và tên Tiếng Anh Hãy trình bày chúng lên màn hình Yêu cầu: Sử dụng kỹ thuật “Display screen asynchronous” Loader ● ●... this.txtCounter.setText("" + 0); //Gọi thực thi AsyncTask new CounterAsyncTask().execute("args as doInBackground"); } Ví dụ class CounterAsyncTask extends AsyncTask { @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...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... ●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 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ử... CounterAsyncTask extends AsyncTask { @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