Bài 35 : Vẽ Button lúc Runtime, dùng Using Message của Handler class


Ở bài tập 34 , Tôi đã trình bày về cách xử lý đa tiến trình dùng Using Message của Handler class, trong bài này cũng với Handler class nhưng Tôi sẽ dùng Using Post để xử lý đa tiến trình. Cụ thể Tôi sẽ cho vẽ các Button động lúc Runtime.

Ví dụ như màn hình dưới đây:

mul5– Khi người sử dụng nhập giá trị vào EditText và nhấn nút DrawButton thì chương trình sẽ vẽ Button đủ số lượng nhập, nếu nó vượt quá màn hình điện thoại thì ta phải cho phép Scroll.

– Các bạn tạo một Project và layout giao diện như hình dưới đây:

mul6

– Tôi trình bày coding MainActivity ở dưới đây:


package tranduythanh.com;

import java.util.concurrent.atomic.AtomicBoolean;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

public class MainActivity extends Activity {

Handler handlerMain;
 AtomicBoolean atomic=null;
 LinearLayout layoutdevebutton;
 Button btnOk;
 EditText edtOk;

@Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //lấy LinearLayout chứa Button ra
 layoutdevebutton=(LinearLayout) findViewById(R.id.layout_draw_button);
 btnOk=(Button) findViewById(R.id.btnDrawButton);
 edtOk=(EditText) findViewById(R.id.editNumber);
 handlerMain=new Handler()
 {
 @Override
 public void handleMessage(Message msg) {
 // TODO Auto-generated method stub
 super.handleMessage(msg);
 //Nhận nhãn của Button được gửi về từ tiến trình con
 String nhan_button=msg.obj.toString();
 //khởi tạo 1 Button
 Button b=new Button(MainActivity.this);
 //thiết lập nhãn cho Button
 b.setText(nhan_button);
 //thiết lập kiểu Layout : Width, Height
 LayoutParams params=new
 LayoutParams(LayoutParams.MATCH_PARENT,
 LayoutParams.WRAP_CONTENT);
 //thiết lập layout cho Button
 b.setLayoutParams(params);
 //đưa Button vào layoutdevebutton
 layoutdevebutton.addView(b);
 }
 };
 btnOk.setOnClickListener(new OnClickListener() {

@Override
 public void onClick(View arg0) {
 // TODO Auto-generated method stub
 doStart();
 }
 });
 }
 private void doStart()
 {
 atomic=new AtomicBoolean(false);
 final int sobutton=Integer.parseInt(edtOk.getText()+"");
 Thread thCon=new Thread(new Runnable() {

 @Override
 public void run() {
 // TODO Auto-generated method stub
 for(int i=0;i<sobutton && atomic.get();i++)
 {
 //nghỉ 200 mili second
 SystemClock.sleep(200);
 //lấy message từ Main Thread
 Message msg=handlerMain.obtainMessage();
 //gán dữ liệu cho msg Mainthread, lưu vào biến obj
 //chú ý ta có thể lưu bất kỳ kiểu dữ liệu nào vào obj
 msg.obj="Button thứ "+i;
 //gửi trả lại message cho Mainthread
 handlerMain.sendMessage(msg);
 }
 }
 });
 atomic.set(true);
 //thực thi tiến trình
 thCon.start();
 }
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.activity_main, menu);
 return true;
 }

}

Bạn hãy cố gắng làm lại bài tập 34, 35 để hiểu cách sử dụng Handler class với Using Message. Bài kế tiếp Tôi sẽ sử dụng Using Post của Handler class để demo đa tiến trình trong việc cập nhật giao diện lúc runtime.

Bạn có thể tải coding mẫu đầy đủ của bài này ở đây: http://www.mediafire.com/download/cpc753fpr9726f9/LearnMultiThreading_usingMessage_DrawButton.rar

Chúc các bạn thành công.

8 responses

  1. Chúc mừng thầy đã trở lại sau bao ngày em mong chờ.

  2. Thầy đã trở lại và lợi hại hơn xưa ^^,cảm ơn những bài viết của thầy ạ

  3. Thầy cho em hỏi: tại sao phải dùng AtomicBoolean mà không dùng 1 biến boolean chẳng hạn, và khi test thì em thấy mặc dù AtomicBoolean.set(false) rồi mà khi gọi tiếp AtomicBoolean.get() thì nó lại trả ra là true chứ không phải false. thầy giải thích được không ạ? Xin cảm ơn thầy!

    1. Hi bạn, mình search trên Google thấy có giải thích như vậy:

      Dùng AtomicBoolean chỉ cho phép một tiến trình chạy tại một thời điểm duy nhất, không cho phép tiến trình khác chạy. Khi tiến trình này chạy xong sẽ cho phép tiến trình khác chạy.

      Bạn tham khảo ở đây nhé:
      http://stackoverflow.com/questions/12035176/java-what-is-the-different-between-atomicboolean-and-a-static-boolean-variable

      Chúc bạn học vui! 😀

  4. Dùng AtomicBoolean(AB) để khi bạn có nhiều thread chạy đang xen nhau dưới nền. Điều này giúp giá trị Boolean của mỗi thread không bị lẫn lộn dẫn đến sai xót (safe thread). Nếu bạn không dùng AB ban phải dùng nhiều biến boolean khác nhau để safe thread.
    Đây chỉ là kiến thức của mình, nếu có thiếu xót vui lòng góp ý để cùng phát triển nhé.

    Cảm ơn thầy Thanh đã chia sẽ những kiến thức bổ ích.
    Linh Nguyen.

  5. […] Bài 35 : Vẽ Button lúc Runtime, dùng Using Message của Handler class […]

  6. bài viết rất hay, nhưng có lẽ chuyên về lập trình thì mới hiểu vấn đề này nhỉ?

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.