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

[polldaddy poll=9764234]

Ở 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:

[code language=”java”]

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;
}

}

[/code]

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 thoughts on “Bài 35 : Vẽ Button lúc Runtime, dùng Using Message của Handler class”

  1. 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! 😀

  2. 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.

Leave a Reply