Giới thiệu
Ví dụ này tạo một đồng hồ số (digital clock) hiển thị trên TextView với hiệu ứng nhấp nháy (blink) giống đồng hồ thực tế, sử dụng Handler và Thread.
Bước 1: Tạo dự án mới
Android Studio → File → New Project.
Bước 2: Giao diện (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp"
android:textStyle="bold"
android:gravity="center"
app:fontFamily="@font/orbitron" />
</LinearLayout>
Lưu ý: Font "orbitron" cần thêm vào thư mục res/font/. Nếu không có, hãy bỏ thuộc tính app:fontFamily.
Bước 3: MainActivity.java
package com.example.andy.myapplication;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
TextView textview;
Handler handler = new Handler();
Runnable blinkRunnable;
Runnable timeRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = findViewById(R.id.textview);
updateTime();
startBlink();
startClock();
}
private void updateTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
textview.setText(sdf.format(new Date()));
}
private void startClock() {
timeRunnable = new Runnable() {
@Override
public void run() {
updateTime();
handler.postDelayed(this, 1000); // Cập nhật mỗi giây
}
};
handler.post(timeRunnable);
}
private void startBlink() {
blinkRunnable = new Runnable() {
@Override
public void run() {
if (textview.getVisibility() == View.VISIBLE) {
textview.setVisibility(View.INVISIBLE);
} else {
textview.setVisibility(View.VISIBLE);
}
handler.postDelayed(this, 500); // Nhấp nháy 500ms
}
};
handler.post(blinkRunnable);
}
@Override
protected void onDestroy() {
super.onDestroy();
// Quan trọng: Remove callbacks để tránh memory leak
handler.removeCallbacks(blinkRunnable);
handler.removeCallbacks(timeRunnable);
}
}
Cải tiến so với code gốc
- Sửa lỗi logic: Code gốc gọi
blink()đệ quy trong thread con gây rò rỉ bộ nhớ. Phiên bản này dùnghandler.postDelayed()an toàn. - Thêm đồng hồ chạy thực tế (cập nhật mỗi giây).
- Dùng
SimpleDateFormat("HH:mm")định dạng 24h (code gốc dùng "HH:MM" sai - MM là tháng). - Cleanup trong
onDestroy()tránh memory leak. - Sử dụng
Locale.getDefault()cho định dạng địa phương.
Chạy ứng dụng

TextView hiển thị giờ:phút và nhấp nháy liên tục.