在 Android 應用開發中,若需實現不同應用程式之間的進程間通訊(IPC),AIDL (Android Interface Definition Language) 是標準解決方案。本文針對初學者,說明如何使用 AIDL 連接 TimerService,並結合 RemoteCallbackList 與 Handler 完成遠端回呼與 UI 更新。
.aidl 檔案,宣告服務端暴露的方法。TimerService 中繼承 Stub 並實作邏輯。bindService 取得遠端介面代理。RemoteCallbackList<ICallback> 管理跨進程的監聽器清單。Handler 更新介面。package com.example.timer;
interface ITimerService {
void registerCallback(ICallback cb);
void unregisterCallback(ICallback cb);
void startTimer(long intervalMs);
}
package com.example.timer;
interface ICallback {
void onTick(long elapsedMs);
}
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
}
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 使用詳解
RemoteCallbackList 必須成對呼叫 beginBroadcast() / finishBroadcast()。Parcelable。