Lập trình Android tiếng Việt - Chapter 13: Android Multi-Threading
Threads
Mỗi thread là một đơn vị thực thi song song (concurrent unit of execution).
Mỗi thread có call stack riêng cho các phương thức được gọi, các tham số và biến địa phương của chúng.
Mỗi thực thể máy ảo (mỗi máy ảo dành cho 1 tiến trình – một ứng dụng đang chạy), khi được chạy, sẽ có ít nhất một thread chính chạy, thông thường có vài thread khác dành cho các nhiệm vụ phục vụ thread chính.
Ứng dụng có thể bật các thread bổ sung để phục vụ các mục đích cụ thể.
ermination if (bar1.getProgress() == MAX_SEC){ msgReturned.setText("Done \n back thread has been stopped"); isRunning = false; } if (bar1.getProgress() == bar1.getMax()){ msgWorking.setText("Done"); bar1.setVisibility(View.INVISIBLE); bar2.setVisibility(View.INVISIBLE); bar1.getLayoutParams().height = 0; bar2.getLayoutParams().height = 0; } else { msgWorking.setText("Working..." + bar1.getProgress() ); } } }; //handler 22 22 22 13. Android – Multi-Threading Multi-Threading 22 Example 1. Progress Bar – Using Message Passing @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); bar1 = (ProgressBar) findViewById(R.id.progress); bar2 = (ProgressBar) findViewById(R.id.progress2); bar1.setMax(MAX_SEC); bar1.setProgress(0); msgWorking = (TextView)findViewById(R.id.TextView01); msgReturned = (TextView)findViewById(R.id.TextView02); strTest += "-01"; // slightly change the global string intTest = 1; }//onCreate public void onStop() { super.onStop(); isRunning = false; } 23 23 23 13. Android – Multi-Threading Multi-Threading 23 Example 1. Progress Bar – Using Message Passing public void onStart() { super.onStart(); // bar1.setProgress(0); Thread background = new Thread(new Runnable() { public void run() { try { for (int i = 0; i 26 26 13. Android – Multi-Threading Multi-Threading 26 Example2. Using Handler post(...) Method // using Handler post(...) method to execute foreground runnables package cis493.threads; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.text.Editable; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class ThreadsPosting extends Activity { ProgressBar myBar; TextView lblTopCaption; EditText txtBox1; Button btnDoSomething; int accum = 0; long startingMills = System.currentTimeMillis(); String PATIENCE = "Some important data is being collected now. " + "\nPlease be patient. “; 27 27 13. Android – Multi-Threading Multi-Threading 27 Example2. Using Handler post(...) Method Handler myHandler = new Handler(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lblTopCaption = (TextView)findViewById(R.id.lblTopCaption); myBar = (ProgressBar) findViewById(R.id.myBar); myBar.setMax(100); txtBox1 = (EditText) findViewById(R.id.txtBox1); txtBox1.setHint("Foreground distraction. Enter some data here"); btnDoSomething = (Button)findViewById(R.id.btnDoSomething); btnDoSomething.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Editable txt = txtBox1.getText(); Toast.makeText(getBaseContext(), "You said >> " + txt, 1).show(); }//onClick });//setOnClickListener }//onCreate 28 28 13. Android – Multi-Threading Multi-Threading 28 Example2. Using Handler post(...) Method @Override protected void onStart() { super.onStart(); // create background thread were the busy work will be done Thread myThread1 = new Thread(backgroundTask, "backAlias1" ); myThread1.start(); myBar.incrementProgressBy(0); } // this is the foreground "Runnable" object responsible for GUI updates private Runnable foregroundTask = new Runnable() { @Override public void run() { try { int progressStep = 5; lblTopCaption.setText(PATIENCE + "\nTotal sec. so far: " + (System.currentTimeMillis() - startingMills) / 1000 ); myBar.incrementProgressBy(progressStep); accum += progressStep; if (accum >= myBar.getMax()){ lblTopCaption.setText("Background work is OVER!"); myBar.setVisibility(View.INVISIBLE); } } catch (Exception e) { e.printStackTrace(); } }//run }; //foregroundTask 29 29 13. Android – Multi-Threading Multi-Threading 29 Example2. Using Handler post(...) Method //this is the "Runnable" object that executes the background thread private Runnable backgroundTask = new Runnable () { @Override public void run() { //busy work goes here... try { for (int n=0; n >", e.getMessage() ); } }//run };//backgroundTask }//ThreadsPosting 30 30 13. Android – Multi-Threading Thread States 30 Thread.State Description BLOCKED is blocked and waiting for a lock. NEW has been created, but has never been started. RUNNABLE may be run. TIMED_WAITING is waiting for a specified amount of time. WAITING is waiting. TERMINATED has been terminated. 31 32 32 32 13. Android – Multi-Threading Multi-Threading 32 Using the AsyncTask class AsyncTask cho phép sử dụng UI thread một cách dễ dàng và đúng cách. AsyncTask cho phép thực hiện các hoạt động background và gửi kết quả cho UI thread mà không phải thao tác với thread và/hoặc handler. Một tác vụ không đồng bộ (asynchronous task) là một nhiệm vụ tính toán chạy tại một background thread và kết quả sẽ được gửi cho UI thread. Một asynchronous task được định nghĩa bởi: 3 kiểu tổng quát (generic) 4 trạng thái chính 1 phương thức bổ trợ Params, Progress, Result onPreExecute, doInBackground, onProgressUpdate onPostExecute. publishProgress 33 33 33 13. Android – Multi-Threading Multi-Threading 33 Using the AsyncTask class private class VerySlowTask extends AsyncTask { // Begin - can use UI thread here protected void onPreExecute() { } // this is the SLOW background thread taking care of heavy tasks // cannot directly change UI protected Void doInBackground(final String... args) { ... publishProgress((Long) someLongValue); } // periodic updates - it is OK to change UI @Override protected void onProgressUpdate(Long... value) { } // End - can use UI thread here protected void onPostExecute(final Void unused) { } } 34 34 34 13. Android – Multi-Threading Multi-Threading 34 Không phải asynchronous task nào cũng dùng đến cả ba kiểu dữ liệu. Đối với kiểu không dùng đến, ta dùng kiểu Void Lưu ý: Cú pháp “String…” có nghĩa (Varargs) mảng gồm các giá trị String, tương tự “String[]” Các tham số kiểu của AsyncTask Params: kiểu dữ liệu của các tham số sẽ được gửi cho task khi nó được thực thi. Progress: kiểu của các progress unit được công bố trong quá trình tính toán tại background (bao nhiêu lâu thì thông báo kết quả tiến độ một lần). Result: kiểu của kết quả tính toán của background. AsyncTask 35 35 35 13. Android – Multi-Threading Multi-Threading 35 AsyncTask's methods onPreExecute(), được gọi tại UI thread ngay trước khi tác vụ (task) được thực thi. Bước này thường dùng để setup tác vụ, chẳng hạn để hiện một progress bar tại giao diện người dùng. doInBackground(Params...), được gọi cho background thread ngay sau khi onPreExecute() chạy xong. Bước này để thực hiện các tính toán background mà có thể tốn thời gian. Các tham số của asynchronous task được truyền cho bước này. Kết quả tính toán phải được trả về bởi bước này và sẽ được truyền lại cho bước cuối cùng. Bước này còn có thể dùng publishProgress(Progress...) để báo cáo một hoặc vài đơn vị tiến độ. Các giá trị này được công bố tại UI thread, trong bước onProgressUpdate(Progress...). onProgressUpdate(Progress...), được gọi cho UI thread sau mỗi lời gọi đến publishProgress(Progress...). Thời điểm thực thi không xác định. Phương thức này được dùng để hiển thị một hình thức tiến độ tùy ý tại giao diện người dùng. Ví dụ, nó có thể là một progress bar hoặc hiện nhật trình (log) tại một text field. onPostExecute(Result), được gọi cho UI thread sau khi công việc tính toán tại background đã xong. Kết quả tính toán của background được truyền cho bước này qua tham số (Result). 36 36 36 36 13. Android – Multi-Threading Multi-Threading 36 Example: Using the AsyncTask class Main task gọi một AsyncTask để làm một công việc tốn thời gian. Các phương thức AsyncTask thực hiện công việc được yêu cầu và định kì cập nhật UI chính. Trong ví dụ này, hoạt động tại background đóng góp vào nội dung của text box và điều khiển progress bar dạng tròn. 37 37 37 37 13. Android – Multi-Threading Multi-Threading 37 Example: Using the AsyncTask class public class Main extends Activity { Button btnSlowWork; Button btnQuickWork; EditText etMsg; Long startingMillis; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); etMsg = (EditText) findViewById(R.id.EditText01); btnSlowWork = (Button) findViewById(R.id.Button01); // delete all data from database (when delete button is clicked) this.btnSlowWork.setOnClickListener(new OnClickListener() { public void onClick(final View v) { new VerySlowTask().execute(); } }); btnQuickWork = (Button) findViewById(R.id.Button02); // delete all data from database (when delete button is clicked) this.btnQuickWork.setOnClickListener(new OnClickListener() { public void onClick(final View v) { etMsg.setText((new Date()).toLocaleString()); } }); }// onCreate 38 38 38 38 13. Android – Multi-Threading Multi-Threading 38 Example: Using the AsyncTask class private class VerySlowTask extends AsyncTask { private final ProgressDialog dialog = new ProgressDialog(Main.this); // can use UI thread here protected void onPreExecute() { startingMillis = System.currentTimeMillis(); etMsg.setText("Start Time: " + startingMillis); this.dialog.setMessage("Wait\nSome SLOW job is being done..."); this.dialog.show(); } // automatically done on worker thread (separate from UI thread) protected Void doInBackground(final String... args) { try { // simulate here the slow activity for (Long i = 0L; i 41 41 13. Android – Multi-Threading Multi-Threading 41 Questions Bài tập Viết một ứng dụng dùng multi-threading để làm việc sau: Số dư tài khoản tự động định kì tăng thêm 15% (lãi nhập gốc) và được hiển thị trên màn hình Nếu người dùng nhập số tiền rồi bấm nút Rút hoặc Gửi thì số tiền sẽ được tăng/giảm tương ứng. Gợi ý: số tiền là biến của activity được các thread dùng chung. dùng một thead để định kì tính lãi và nhập gốc UI thread dùng các listener cho các Button để xử lý event bấm nút Rút/Gửi 100.000 Số dư tài khoản Gửi 10.000 Rút
File đính kèm:
- Lập trình Android tiếng Việt - Chapter 13 Android Multi-Threading.pptx