You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.NET MAUI中绑定Android服务:OnServiceConnected未触发

.NET MAUI绑定Android服务时OnServiceConnected未触发(BindService返回true)

我在.NET MAUI中尝试绑定Zebra的RFID Android服务,相同逻辑的Kotlin代码可以正常运行,但.NET环境下OnServiceConnected始终未被调用,尽管BindService返回true。怀疑遗漏了关键细节但尚未定位到原因。

以下是相关代码:

AIDL接口定义

package com.zebra.rfid.api3;

interface IRFIDDeviceInterface {
    void ledBlink();
}

.NET MAUI中的C#代码

public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        var r = new RfidDeviceService(this);

        Task.Run(async () =>
            {
                r.Bind();
                while (true)
                {
                    await Task.Delay(1000);

                    if (r.ServiceConnection.rfidDeviceInterface != null)
                    {
                        r.ServiceConnection.rfidDeviceInterface.LedBlink();
                    }
                    else
                    {
                        Console.WriteLine("nope");
                    }
                }
            });
    }
}

public class ServiceConnection : Java.Lang.Object, IServiceConnection
{
    public IRFIDDeviceInterface rfidDeviceInterface;

    public void OnServiceConnected(ComponentName name, IBinder service)
    {
        rfidDeviceInterface = IRFIDDeviceInterfaceStub.AsInterface(service);
    }

    public void OnServiceDisconnected(ComponentName name)
    {
        rfidDeviceInterface = null;
    }
}

public class RfidDeviceService
{
    public ServiceConnection ServiceConnection;
    private Context appContext;

    public RfidDeviceService(Context context)
    {
        ServiceConnection = new ServiceConnection();
        appContext = context;
    }

    public void Bind()
    {
        var serviceIntent = new Intent(nameof(IRFIDDeviceInterface));
        serviceIntent.SetClassName("com.zebra.rfid.rfidmanager", "com.zebra.rfid.rfidmanager.RFIDService");

        var result = appContext.BindService(serviceIntent, ServiceConnection, global::Android.Content.Bind.AutoCreate);
        Console.WriteLine($"Binded {result}");
    }
}

可能的问题点及修复方案

1. Intent构造错误

.NET中nameof(IRFIDDeviceInterface)仅返回字符串"IRFIDDeviceInterface",但Android AIDL接口的Action默认是完整包名+接口名,即com.zebra.rfid.api3.IRFIDDeviceInterface。修改Bind方法中的Intent构造:

var serviceIntent = new Intent("com.zebra.rfid.api3.IRFIDDeviceInterface");

2. ServiceConnection生命周期回收风险

当前ServiceConnection作为RfidDeviceService的成员,可能被GC提前回收。将其提升为Activity成员变量延长生命周期:

// 修改MainActivity
private RfidDeviceService _rfidService;
private ServiceConnection _serviceConnection;

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    _serviceConnection = new ServiceConnection();
    _rfidService = new RfidDeviceService(this, _serviceConnection);

    Task.Run(async () =>
        {
            _rfidService.Bind();
            while (true)
            {
                await Task.Delay(1000);

                if (_serviceConnection.rfidDeviceInterface != null)
                {
                    _serviceConnection.rfidDeviceInterface.LedBlink();
                }
                else
                {
                    Console.WriteLine("nope");
                }
            }
        });
}

// 修改RfidDeviceService构造
public RfidDeviceService(Context context, ServiceConnection connection)
{
    ServiceConnection = connection;
    appContext = context;
}

3. 缺失权限声明

在AndroidManifest.xml中添加Zebra RFID服务所需权限:

<uses-permission android:name="com.zebra.rfid.api3.permission.ACCESS_RFID" />

4. 主线程执行绑定操作

将Bind调用移至主线程(BindService允许后台调用,但回调在主线程,避免潜在的线程问题):

RunOnUiThread(() => _rfidService.Bind());

5. 验证AIDL存根生成正确性

检查自动生成的IRFIDDeviceInterfaceStub代码,确保AsInterface方法能正确将IBinder转换为接口实例,确认存根类继承自Android.OS.Binder并正确实现接口方法。

内容的提问来源于stack exchange,提问作者Danny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:14:51