首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android AIDL 跨程序通訊實作入門指南

     編輯:程式設計疑難解答

需求背景

在 Android 應用開發中,若需實現不同應用程式之間的進程間通訊(IPC),AIDL (Android Interface Definition Language) 是標準解決方案。本文針對初學者,說明如何使用 AIDL 連接 TimerService,並結合 RemoteCallbackList 與 Handler 完成遠端回呼與 UI 更新。

核心步驟

  1. 定義 AIDL 介面:建立 .aidl 檔案,宣告服務端暴露的方法。
  2. 實作 Service:在 TimerService 中繼承 Stub 並實作邏輯。
  3. 客戶端綁定服務:使用 bindService 取得遠端介面代理。
  4. 遠端回呼:利用 RemoteCallbackList<ICallback> 管理跨進程的監聽器清單。
  5. UI 更新:在主執行緒透過 Handler 更新介面。

關鍵程式碼片段

1. AIDL 介面 (ITimerService.aidl)

package com.example.timer;

interface ITimerService {
    void registerCallback(ICallback cb);
    void unregisterCallback(ICallback cb);
    void startTimer(long intervalMs);
}

2. 回呼介面 (ICallback.aidl)

package com.example.timer;

interface ICallback {
    void onTick(long elapsedMs);
}

3. 服務端實作

public class TimerService extends Service {
    private final RemoteCallbackList<ICallback> callbacks = new RemoteCallbackList<>();
    private Handler handler = new Handler(Looper.getMainLooper());
    private Runnable tickRunnable;

    private final ITimerService.Stub binder = new ITimerService.Stub() {
        @Override
        public void registerCallback(ICallback cb) {
            callbacks.register(cb);
        }
        @Override
        public void unregisterCallback(ICallback cb) {
            callbacks.unregister(cb);
        }
        @Override
        public void startTimer(long intervalMs) {
            // 啟動定時任務,定時呼叫 broadcastTick()
        }
    };

    private void broadcastTick(long elapsed) {
        int n = callbacks.beginBroadcast();
        for (int i = 0; i < n; i++) {
            try {
                callbacks.getBroadcastItem(i).onTick(elapsed);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        callbacks.finishBroadcast();
    }
    // ... onBind 回傳 binder
}

4. 客戶端綁定與 UI 更新

private ITimerService remoteService;
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        remoteService = ITimerService.Stub.asInterface(service);
        try {
            remoteService.registerCallback(new ICallback.Stub() {
                @Override
                public void onTick(long elapsedMs) {
                    // 切換到主執行緒更新 UI
                    new Handler(Looper.getMainLooper()).post(() -> {
                        textView.setText("Elapsed: " + elapsedMs + " ms");
                    });
                }
            });
            remoteService.startTimer(1000);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    // ... onServiceDisconnected
};

學習資源推薦

更完整的範碼與說明可參考:CSDN 部落格 - AIDL 使用詳解

常見坑點提醒

  • AIDL 檔案放置路徑必須與包名對應,且 Server/Client 專案需共用相同的 AIDL 定義。
  • RemoteCallbackList 必須成對呼叫 beginBroadcast() / finishBroadcast()。
  • 跨進程傳遞的物件需實作 Parcelable。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved