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

Android實(shí)現(xiàn)界面定時(shí)刷新功能

 更新時(shí)間:2025年04月21日 08:48:13   作者:Katie。  
在移動應(yīng)用中,界面定時(shí)刷新是非常常見的需求,本教程將以一個(gè)“實(shí)時(shí)時(shí)鐘”示例為主線,演示多種常用的定時(shí)刷新的實(shí)現(xiàn)方式,并對比它們的代碼簡潔度、性能消耗、生命周期管理與取消機(jī)制,幫助您在項(xiàng)目中快速選型并上手,需要的朋友可以參考下

一、項(xiàng)目介紹

在移動應(yīng)用中,界面定時(shí)刷新是非常常見的需求,典型場景包括:

  1. 時(shí)鐘/秒表:每秒更新顯示當(dāng)前時(shí)間或計(jì)時(shí);

  2. 實(shí)時(shí)數(shù)據(jù)監(jiān)控:定期拉取服務(wù)器狀態(tài)或傳感器數(shù)據(jù)并更新 UI;

  3. 列表自動刷新:如新聞、社交Feeds 定時(shí)刷新最新內(nèi)容;

  4. 倒計(jì)時(shí):在促銷、考試倒計(jì)時(shí)場景下每秒更新剩余時(shí)長;

  5. 游戲邏輯刷新:簡單動畫或狀態(tài)輪詢。

本教程將以一個(gè)“實(shí)時(shí)時(shí)鐘”示例為主線,演示多種常用的定時(shí)刷新的實(shí)現(xiàn)方式:

  • 方案 A:Handler + postDelayed

  • 方案 B:Timer + Handler

  • 方案 C:ScheduledExecutorService

  • 方案 D:RxJava interval

  • 方案 E:Kotlin Coroutines + Flow

并對比它們的代碼簡潔度性能消耗、生命周期管理取消機(jī)制,幫助您在項(xiàng)目中快速選型并上手。

二、相關(guān)技術(shù)與知識

  1. 主線程與 UI 更新

    • Android 要求所有 UI 操作必須在主線程(UI 線程)中執(zhí)行。

    • 定時(shí)任務(wù)若在子線程中執(zhí)行,需要切回主線程使用 runOnUiThread() 或 Handler。

  2. Handler & Looper

    • Handler:將 Runnable 或 Message 發(fā)布到所綁定的 Looper(線程消息隊(duì)列)。

    • postDelayed(Runnable r, long delayMillis):延遲執(zhí)行任務(wù)。

  3. Timer & TimerTask

    • Timer 用于安排 TimerTask 在后臺線程周期或延遲執(zhí)行;

    • 結(jié)果需要通過 Handler 或 runOnUiThread() 回到主線程。

  4. ScheduledExecutorService

    • Java 標(biāo)準(zhǔn)庫:Executors.newSingleThreadScheduledExecutor() 可定期執(zhí)行任務(wù),支持 scheduleAtFixedRate()。

  5. RxJava

    • Observable.interval():基于 Scheduler 定時(shí)發(fā)射 Long 值,結(jié)合 observeOn(AndroidSchedulers.mainThread()) 更新 UI。

  6. Kotlin Coroutines & Flow

    • flow { while(true) { emit(Unit); delay(1000) } }:使用協(xié)程輕量定時(shí);

    • 在 lifecycleScope.launchWhenStarted 中收集并更新 UI。

  7. 生命周期管理與取消

    • 定時(shí)任務(wù)應(yīng)在 Activity.onPause()/onDestroy() 中取消,避免內(nèi)存泄漏與后臺無用計(jì)算;

    • 不同方案的取消方式也不同:Handler.removeCallbacks(),timer.cancel()future.cancel()disposable.dispose(),job.cancel() 等。

三、實(shí)現(xiàn)思路

  1. 示例界面設(shè)計(jì)

    • 一個(gè) TextView 用于顯示當(dāng)前時(shí)間(格式:HH:mm:ss);

    • 一個(gè)“開始”與“停止”按鈕,控制定時(shí)刷新;

    • 布局簡單,整合到 MainActivity 注釋中。

  2. 核心方法封裝

    • updateTime():獲取系統(tǒng)當(dāng)前時(shí)間并格式化 tvClock.setText(...)

    • 對于每種方案,在“開始”時(shí)啟動定時(shí)任務(wù),每次調(diào)用 updateTime();

    • 在“停止”時(shí)取消任務(wù)并停止刷新。

  3. 生命周期鉤子

    • 在 onPause() 或 onDestroy() 中統(tǒng)一調(diào)用 stopX() 方法,確保任務(wù)取消。

  4. 對比與選型

    • 在項(xiàng)目初期可使用最簡單的 Handler.postDelayed;

    • 若需要高可控或并發(fā)任務(wù),可選擇 ScheduledExecutorService;

    • 如果已引入 RxJava 或使用 Kotlin,推薦相應(yīng)方案。

四、完整代碼

// ==============================================
// 文件:MainActivity.java
// 功能:演示五種方式實(shí)現(xiàn)界面定時(shí)刷新(實(shí)時(shí)時(shí)鐘示例)
// 包含布局 XML、Gradle 依賴一處整合,詳細(xì)注釋
// ==============================================
 
package com.example.timerrefresh;
 
import android.os.*;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
 
// RxJava 依賴
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.*;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
 
// Kotlin Coroutines & Flow 依賴(需 Kotlin 支持)
// import kotlinx.coroutines.*
// import kotlinx.coroutines.flow.*
 
// Java 并發(fā)
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;
 
public class MainActivity extends AppCompatActivity {
    private TextView tvClock;
    private Button btnStart, btnStop;
 
    // --- 方案 A: Handler + postDelayed ---
    private Handler handler = new Handler(Looper.getMainLooper());
    private Runnable taskA = new Runnable() {
        @Override public void run() {
            updateTime();
            handler.postDelayed(this, 1000);
        }
    };
 
    // --- 方案 B: Timer + Handler ---
    private Timer timerB;
    private TimerTask timerTaskB;
 
    // --- 方案 C: ScheduledExecutorService ---
    private ScheduledExecutorService schedulerC;
    private ScheduledFuture<?> futureC;
 
    // --- 方案 D: RxJava interval ---
    private Disposable disposableD;
 
    // --- 方案 E: Kotlin Coroutines + Flow ---
    // private Job jobE;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);  // 布局整合在注釋下方
 
        tvClock   = findViewById(R.id.tvClock);
        btnStart  = findViewById(R.id.btnStart);
        btnStop   = findViewById(R.id.btnStop);
 
        btnStart.setOnClickListener(v -> {
            // 選擇下面一種,注釋其余
            startA();
            // startB();
            // startC();
            // startD();
            // startE();
        });
        btnStop.setOnClickListener(v -> {
            stopA();
            stopB();
            stopC();
            stopD();
            stopE();
        });
    }
 
    /** 更新時(shí)鐘顯示 */
    private void updateTime() {
        String now = new SimpleDateFormat(
            "HH:mm:ss", Locale.getDefault())
            .format(new Date());
        tvClock.setText(now);
    }
 
    // === 方案 A:Handler + postDelayed ===
    private void startA() {
        handler.post(taskA);
    }
    private void stopA() {
        handler.removeCallbacks(taskA);
    }
 
    // === 方案 B:Timer + Handler ===
    private void startB() {
        timerB = new Timer();
        timerTaskB = new TimerTask() {
            @Override public void run() {
                handler.post(() -> updateTime());
            }
        };
        timerB.scheduleAtFixedRate(timerTaskB, 0, 1000);
    }
    private void stopB() {
        if (timerB != null) {
            timerB.cancel();
            timerB = null;
        }
    }
 
    // === 方案 C:ScheduledExecutorService ===
    private void startC() {
        schedulerC = Executors.newSingleThreadScheduledExecutor();
        futureC = schedulerC.scheduleAtFixedRate(() -> {
            runOnUiThread(this::updateTime);
        }, 0, 1, TimeUnit.SECONDS);
    }
    private void stopC() {
        if (futureC != null) futureC.cancel(true);
        if (schedulerC != null) schedulerC.shutdown();
    }
 
    // === 方案 D:RxJava interval ===
    private void startD() {
        disposableD = Observable.interval(0, 1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(x -> updateTime());
    }
    private void stopD() {
        if (disposableD != null && !disposableD.isDisposed()) {
            disposableD.dispose();
        }
    }
 
    // === 方案 E:Kotlin Coroutines + Flow ===
    /*
    private void startE() {
        jobE = CoroutineScope(Dispatchers.Main).launch {
            flow {
                while (true) {
                    emit(Unit)
                    delay(1000)
                }
            }.collect {
                updateTime()
            }
        };
    }
    private void stopE() {
        if (jobE != null && jobE.isActive()) {
            jobE.cancel();
        }
    }
    */
 
    @Override protected void onDestroy() {
        super.onDestroy();
        // 確保停止所有方案
        stopA(); stopB(); stopC(); stopD(); stopE();
    }
}
 
/*
=========================== res/layout/activity_main.xml ===========================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:gravity="center"
    android:padding="24dp"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <TextView
        android:id="@+id/tvClock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="--:--:--"
        android:textSize="48sp"
        android:textStyle="bold"/>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_marginTop="32dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btnStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="開始刷新"/>
        <Button
            android:id="@+id/btnStop"
            android:layout_marginStart="16dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="停止刷新"/>
    </LinearLayout>
</LinearLayout>
=========================== 布局結(jié)束 ===========================
*/
 
/*
=========================== app/build.gradle 關(guān)鍵依賴 ===========================
dependencies {
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'io.reactivex.rxjava3:rxjava:3.1.5'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    // Kotlin Coroutines & Flow(如需要示例 E)
    // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
    // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
}
=========================== Gradle 結(jié)束 ===========================
*/

五、方法解讀

  1. Handler + postDelayed

    • 優(yōu)點(diǎn):代碼最簡潔,無額外依賴;

    • 缺點(diǎn):單線程串行,不易并行多個(gè)定時(shí)任務(wù);

  2. Timer + Handler

    • 優(yōu)點(diǎn):邏輯清晰,直接在后臺線程周期執(zhí)行;

    • 缺點(diǎn)Timer 無法感知 UI 生命周期,需要手動取消;若任務(wù)拋異常會終止調(diào)度。

  3. ScheduledExecutorService

    • 優(yōu)點(diǎn):功能強(qiáng)大,可自定義線程池大小與策略;

    • 缺點(diǎn):稍顯冗長,但更適合多個(gè)并發(fā)定時(shí)任務(wù)。

  4. RxJava interval

    • 優(yōu)點(diǎn):鏈?zhǔn)秸{(diào)用、易于組合,可與其他 Rx 流無縫銜接;

    • 缺點(diǎn):需引入 RxJava 庫,學(xué)習(xí)門檻較高;

  5. Kotlin Coroutines + Flow

    • 優(yōu)點(diǎn):語言級支持,寫法像同步,易讀易寫;

    • 缺點(diǎn):需 Kotlin 環(huán)境,注意協(xié)程生命周期管理;

六、項(xiàng)目總結(jié)

  • 選擇建議

    • 最簡單:僅需單一定時(shí)在 UI 線程更新 → 方案 A;

    • 復(fù)用需求:多處定時(shí)、可復(fù)用同一線程 → 方案 B/C

    • 已有 RxJava:推薦 方案 D;

    • Kotlin 項(xiàng)目:首選 方案 E

  • 生命周期注意:所有定時(shí)任務(wù)都需在 onDestroy()、onPause() 或 onStop() 中取消,避免內(nèi)存泄漏與后臺無用計(jì)算。

  • 精細(xì)調(diào)度

    • 若對“漂移”敏感,可使用 scheduleAtFixedRate();

    • 若后續(xù)任務(wù)執(zhí)行時(shí)間不可控,推薦 scheduleWithFixedDelay()。

  • 性能優(yōu)化:避免在定時(shí)任務(wù)中執(zhí)行過重運(yùn)算或 Block UI;對于高精度(<100ms)定時(shí)可選更底層方案如 Choreographer。

到此這篇關(guān)于Android實(shí)現(xiàn)界面定時(shí)刷新功能的文章就介紹到這了,更多相關(guān)Android界面定時(shí)刷新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論