Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách cập nhật UI liên tục từ IntentService trong Android

Giới thiệu

Ví dụ này minh họa cách IntentService gửi nhiều broadcast liên tục để cập nhật UI Activity theo thời gian thực.

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"?>
<android.support.constraint.ConstraintLayout 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">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Khởi động Service"
        android:textSize="25sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Bước 3: MainActivity với Timer tự động start Service (src/MainActivity.java)

package com.example.andy.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {
    TextView text;
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String value = intent.getStringExtra("someName");
            text.setText(value);
        }
    };

    @Override
    protected void onStart() {
        super.onStart();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.example.andy.myapplication");
        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, filter);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = findViewById(R.id.text);

        // Timer tự động start service mỗi 10 giây
        Handler handler = new Handler();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                handler.post(() -> startService(new Intent(MainActivity.this, ContinuousService.class)));
            }
        };
        new Timer().schedule(task, 0, 10000);
    }

    @Override
    protected void onStop() {
        super.onStop();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
    }
}

Bước 4: Service gửi nhiều broadcast (ContinuousService.java)

package com.example.andy.myapplication;

import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;

public class ContinuousService extends IntentService {
    public static volatile boolean shouldStop = false;

    public ContinuousService() {
        super(ContinuousService.class.getSimpleName());
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Intent broadcastIntent = new Intent("com.example.andy.myapplication");
        for (int i = 0; i < 10; i++) {
            broadcastIntent.putExtra("someName", "Tutorialspoint.com " + i);
            LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
            try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
        }
        if (shouldStop) { stopSelf(); }
    }
}

Giải thích luồng dữ liệu

  1. MainActivity: Timer.schedule mỗi 10s → startService()
  2. Service: Vòng lặp 10 lần, mỗi lần sendBroadcast + sleep 1s
  3. MainActivity: BroadcastReceiver nhận → cập nhật TextView

Chạy ứng dụng

Chạy app → TextView cập nhật liên tục: "Tutorialspoint.com 0" → "Tutorialspoint.com 1" → ... → "Tutorialspoint.com 9" → (10s sau lặp lại).

⚠️ Kiến trúc hiện đại: IntentService deprecated API 30. Nên dùng WorkManager (periodic work) + LiveData/Flow'observable pattern cho UI updates.