欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Handler 的用法指南

 更新時(shí)間:2025年04月03日 10:59:42   作者:滬cares  
Handler 是 Android 中用于線(xiàn)程間通信的重要機(jī)制,主要用于在不同線(xiàn)程之間發(fā)送和處理消息,下面給大家分享Android Handler 的用法指南,感興趣的朋友一起看看吧

Android 中 Handler 的用法詳解

Handler 是 Android 中用于線(xiàn)程間通信的重要機(jī)制,主要用于在不同線(xiàn)程之間發(fā)送和處理消息。以下是 Handler 的全面用法指南:

一、Handler 的基本原理

Handler 基于消息隊(duì)列(MessageQueue)和循環(huán)器(Looper)工作,主要組成:

  • Message:攜帶數(shù)據(jù)的消息對(duì)象
  • MessageQueue:消息隊(duì)列,存儲(chǔ)待處理的消息
  • Looper:消息循環(huán),不斷從隊(duì)列取出消息處理
  • Handler:發(fā)送和處理消息的接口

二、基本用法

1. 創(chuàng)建 Handler(主線(xiàn)程)

// 在主線(xiàn)程創(chuàng)建Handler會(huì)自動(dòng)關(guān)聯(lián)主線(xiàn)程的Looper
Handler mainHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        // 處理消息
        switch (msg.what) {
            case 1:
                String text = (String) msg.obj;
                textView.setText(text);
                break;
        }
    }
};

2. 發(fā)送消息

// 發(fā)送空消息
handler.sendEmptyMessage(1);
// 發(fā)送帶what的消息
Message msg = handler.obtainMessage();
msg.what = 2;
msg.obj = "Hello Handler";
handler.sendMessage(msg);
// 延遲發(fā)送
handler.sendEmptyMessageDelayed(1, 1000); // 1秒后發(fā)送
handler.sendMessageDelayed(msg, 2000); // 2秒后發(fā)送

3. 在子線(xiàn)程使用 Handler

new Thread(() -> {
    // 為當(dāng)前線(xiàn)程創(chuàng)建Looper
    Looper.prepare();
    Handler threadHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // 處理子線(xiàn)程消息
        }
    };
    // 開(kāi)始消息循環(huán)
    Looper.loop();
}).start();

三、Handler 的常見(jiàn)使用場(chǎng)景

1. 更新 UI

new Thread(() -> {
    // 模擬耗時(shí)操作
    try {
        Thread.sleep(1000);
        // 通過(guò)Handler發(fā)送消息到主線(xiàn)程更新UI
        Message msg = mainHandler.obtainMessage();
        msg.what = 1;
        msg.obj = "更新后的文本";
        mainHandler.sendMessage(msg);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();

2. 定時(shí)任務(wù)

// 延遲執(zhí)行
handler.postDelayed(() -> {
    Toast.makeText(this, "5秒后執(zhí)行", Toast.LENGTH_SHORT).show();
}, 5000);
// 循環(huán)執(zhí)行
final Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // 執(zhí)行任務(wù)
        Log.d("Handler", "每隔1秒執(zhí)行");
        // 再次post實(shí)現(xiàn)循環(huán)
        handler.postDelayed(this, 1000);
    }
};
handler.postDelayed(runnable, 1000);
// 取消定時(shí)任務(wù)
handler.removeCallbacks(runnable);

3. 線(xiàn)程間通信

// 工作線(xiàn)程
class WorkerThread extends Thread {
    public Handler workerHandler;
    @Override
    public void run() {
        Looper.prepare();
        workerHandler = new Handler(Looper.myLooper()) {
            @Override
            public void handleMessage(Message msg) {
                // 處理來(lái)自主線(xiàn)程的消息
                String task = (String) msg.obj;
                Log.d("WorkerThread", "執(zhí)行任務(wù): " + task);
                // 可以回傳結(jié)果給主線(xiàn)程
                Message resultMsg = mainHandler.obtainMessage();
                resultMsg.what = 2;
                resultMsg.obj = task + " 完成";
                mainHandler.sendMessage(resultMsg);
            }
        };
        Looper.loop();
    }
}
// 主線(xiàn)程發(fā)送任務(wù)給工作線(xiàn)程
WorkerThread worker = new WorkerThread();
worker.start();
// 等待workerHandler初始化
new Handler().postDelayed(() -> {
    if (worker.workerHandler != null) {
        Message msg = worker.workerHandler.obtainMessage();
        msg.obj = "下載文件";
        worker.workerHandler.sendMessage(msg);
    }
}, 1000);

四、高級(jí)用法

1. 使用 HandlerThread

// 創(chuàng)建HandlerThread
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
// 獲取HandlerThread的Looper創(chuàng)建Handler
Handler threadHandler = new Handler(handlerThread.getLooper()) {
    @Override
    public void handleMessage(Message msg) {
        // 在后臺(tái)線(xiàn)程處理消息
    }
};
// 發(fā)送消息
threadHandler.post(() -> {
    // 在HandlerThread中執(zhí)行
});
// 退出時(shí)釋放資源
handlerThread.quitSafely();

2. 避免內(nèi)存泄漏

// 使用靜態(tài)內(nèi)部類(lèi)+弱引用
private static class SafeHandler extends Handler {
    private final WeakReference<Activity> activityRef;
    public SafeHandler(Activity activity) {
        super(Looper.getMainLooper());
        this.activityRef = new WeakReference<>(activity);
    }
    @Override
    public void handleMessage(Message msg) {
        Activity activity = activityRef.get();
        if (activity != null && !activity.isFinishing()) {
            // 安全處理消息
        }
    }
}
// 在Activity中使用
private SafeHandler safeHandler = new SafeHandler(this);

3. 使用 Message 的優(yōu)化

// 復(fù)用Message對(duì)象(推薦)
Message msg = handler.obtainMessage(WHAT_ARG, obj);
handler.sendMessage(msg);
// 設(shè)置回調(diào)代替繼承Handler
handler.sendMessage(Message.obtain(handler, () -> {
    // 回調(diào)處理
}));

五、注意事項(xiàng)

  • 線(xiàn)程安全:Handler 與創(chuàng)建它的線(xiàn)程綁定,不能跨線(xiàn)程直接使用
  • 內(nèi)存泄漏:非靜態(tài) Handler 內(nèi)部類(lèi)會(huì)持有外部類(lèi)引用,Activity 銷(xiāo)毀時(shí)要移除回調(diào)
  • Looper 準(zhǔn)備:子線(xiàn)程使用 Handler 必須先調(diào)用 Looper.prepare()
  • 消息堆積:避免發(fā)送過(guò)多消息導(dǎo)致消息隊(duì)列堵塞
  • 及時(shí)清理:在 onDestroy() 中移除所有回調(diào)
@Override
protected void onDestroy() {
    super.onDestroy();
    handler.removeCallbacksAndMessages(null);
    if (handlerThread != null) {
        handlerThread.quitSafely();
    }
}

到此這篇關(guān)于Android Handler 的用法詳解的文章就介紹到這了,更多相關(guān)Android Handler 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android實(shí)現(xiàn)手電筒電源鍵關(guān)閉功能

    Android實(shí)現(xiàn)手電筒電源鍵關(guān)閉功能

    這篇文章主要介紹了Android實(shí)現(xiàn)手電筒電源鍵關(guān)閉功能,在打開(kāi)手電筒之后,機(jī)器休眠,客戶(hù)要求點(diǎn)擊電源鍵,手電筒需要關(guān)閉,下面小編給大家分享實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2017-11-11
  • Android AOP 注解詳解及簡(jiǎn)單使用實(shí)例(三)

    Android AOP 注解詳解及簡(jiǎn)單使用實(shí)例(三)

    這篇文章主要介紹了Android AOP 注解詳解及簡(jiǎn)單使用實(shí)例(三)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Android7.0中關(guān)于ContentProvider組件詳解

    Android7.0中關(guān)于ContentProvider組件詳解

    本文描述了Android7.0中關(guān)于ContentProvider組件實(shí)現(xiàn)原理以及ContentProvider發(fā)布者和調(diào)用者這兩在Framework層是如何實(shí)現(xiàn)的。
    2017-11-11
  • Flutter利用ORM框架簡(jiǎn)化本地?cái)?shù)據(jù)庫(kù)管理詳解

    Flutter利用ORM框架簡(jiǎn)化本地?cái)?shù)據(jù)庫(kù)管理詳解

    使用?sqflite?相對(duì)來(lái)說(shuō)還是有點(diǎn)復(fù)雜,比如遇到數(shù)據(jù)不兼容的時(shí)候需要手動(dòng)轉(zhuǎn)換,增加了不少繁瑣的代碼。本篇我們就來(lái)介紹一個(gè)?ORM?框架,來(lái)簡(jiǎn)化數(shù)據(jù)庫(kù)的管理,感興趣的可以了解一下
    2023-04-04
  • Android開(kāi)發(fā)中CheckBox的簡(jiǎn)單用法示例

    Android開(kāi)發(fā)中CheckBox的簡(jiǎn)單用法示例

    這篇文章主要介紹了Android開(kāi)發(fā)中CheckBox的簡(jiǎn)單用法,結(jié)合實(shí)例形式分析了Android中CheckBox控件的基本功能設(shè)置與頁(yè)面布局技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Android開(kāi)發(fā)中的ViewModel使用實(shí)戰(zhàn)案例

    Android開(kāi)發(fā)中的ViewModel使用實(shí)戰(zhàn)案例

    在Android應(yīng)用開(kāi)發(fā)中,ViewModel作為架構(gòu)組件,重要的功能是管理UI數(shù)據(jù)與生命周期,文章深入分析ViewModel如何感知View的生命周期,以及其核心優(yōu)勢(shì),包括生命周期感知、數(shù)據(jù)持久化和與UI層解耦,幫助開(kāi)發(fā)者利用ViewModel優(yōu)化應(yīng)用架構(gòu),需要的朋友可以參考下
    2024-10-10
  • Android超詳細(xì)講解組件ScrollView的使用

    Android超詳細(xì)講解組件ScrollView的使用

    本節(jié)帶來(lái)的是Android基本UI控件中的第十個(gè):ScrollView(滾動(dòng)條),或者我們應(yīng)該叫他?豎直滾動(dòng)條,對(duì)應(yīng)的另外一個(gè)水平方向上的滾動(dòng)條:HorizontalScrollView,先讓我們來(lái)了解ScrollView
    2022-03-03
  • android中Fragment+RadioButton實(shí)現(xiàn)底部導(dǎo)航欄

    android中Fragment+RadioButton實(shí)現(xiàn)底部導(dǎo)航欄

    本篇文章主要介紹了android中Fragment+RadioButton實(shí)現(xiàn)底部導(dǎo)航欄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Android開(kāi)發(fā)之電話(huà)撥號(hào)器實(shí)例詳解

    Android開(kāi)發(fā)之電話(huà)撥號(hào)器實(shí)例詳解

    這篇文章主要介紹了Android開(kāi)發(fā)之電話(huà)撥號(hào)器,結(jié)合實(shí)例形式詳細(xì)分析了Android電話(huà)撥號(hào)器的實(shí)現(xiàn)步驟與具體代碼,并附帶了一個(gè)Android開(kāi)放電話(huà)撥號(hào)器的學(xué)習(xí)筆記,需要的朋友可以參考下
    2015-12-12
  • Android 實(shí)現(xiàn)不同字體顏色的TextView實(shí)現(xiàn)代碼

    Android 實(shí)現(xiàn)不同字體顏色的TextView實(shí)現(xiàn)代碼

    這篇文章主要介紹了Android 實(shí)現(xiàn)不同字體顏色的TextView實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05

最新評(píng)論