绑定远程服务(AIDL)

3

有许多关于StackOverflow和网络指南的问题,包括Android有关此特定功能的官方文档。

我相信我已经逐字遵循了所有的指示和细微差别,但这是一些参考问题,我用来尝试解决我的问题:

两个应用程序之间的AIDL接口
服务未绑定
Android: 绑定到远程服务

我遇到的问题是找不到Service本身。无论它是否正在运行,我都会遇到以下错误:

无法启动Intent { cmp=com.example.dumpsterfire/.DumpsterService } U=0的服务:未找到

这是两个应用程序的相关配置

DumpsterFire (服务器/服务源代码)

build.gradle.kts

plugins {
    id("com.android.application")
    id("kotlin-android")
}

android {
    compileSdkVersion(30)
    buildToolsVersion = "30.0.3"

    defaultConfig {
        applicationId = "com.example.dumpsterfire"
        minSdkVersion(24)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    implementation(fileTree("/libs") { include("*.jar", "*.aar") })

    implementation("androidx.core:core-ktx:1.3.2")
    implementation("androidx.appcompat:appcompat:1.2.0")
    implementation("com.google.android.material:material:1.2.1")
    implementation("androidx.constraintlayout:constraintlayout:2.0.4")
    testImplementation("junit:junit:4.13.1")
    androidTestImplementation("androidx.test.ext:junit:1.1.2")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
}

AndroidManifest: 安卓清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dumpsterfire">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DumpsterFire">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".DumpsterService"
            android:enabled="true"
            android:exported="true" />
    </application>

</manifest>

DumpsterService.kt

class DumpsterService : Service() {
    override fun onBind(intent: Intent?): IBinder {
        return object : IDemoAidl.Stub() {
            override fun printAcross(message: String?) {
                Log.d("chaser", "Hello, I've been instructed to say:\n$message")
            }
        }
    }
}

IDemoAidl.aidl

interface IDemoAidl {
    void printAcross(String message);
}

客户端废纸篓 (Client/Service binder)

MainActivity.kt

//...
override fun onCreate(savedInstanceState: Bundle?) {
    //...
    bindService(
            Intent().setClassName("com.example.dumpsterfire", ".DumpsterService"),
            connection,
            BIND_AUTO_CREATE
    )
}

val connection = object : ServiceConnection {
    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        IDemoAidl.Stub.asInterface(service)
                .printAcross("Assuming direct control")
    }

    override fun onServiceDisconnected(name: ComponentName?) {
        Log.d("chaser", "host service terminated")
    }
}
//...

IDemoAidl.aidl

interface IDemoAidl {
    void printAcross(String message);
}

P.S. 我尝试过在后台运行相关的服务,并通过adb shell命令dumpsys activity services验证其存在性。但这并没有改变我收到的错误信息。

P.P.S. 我也尝试过以下方法:

  • 从头重新安装两个应用程序。
  • 进行清洁构建。
  • 清除缓存/重启。

另一个想法是,在使用客户端之前,您是否曾经从“服务器”应用程序运行过任何活动?我非常确定在用户运行活动之前,服务和广播接收器都已被禁用。 - Selvin
@Selvin 是的,DumpsterFire 应用程序有一个活动,并且在 DumpsterClient 安装/启动之前已经被安装/启动过了。 - nukeforum
我对这些包非常确定。但如果有帮助的话,我可以发布完整的清单和 build.gradle 文件。明确一下,我已经从 DumpsterFire 中显式运行了 DumpsterService 并使用 dumpsys activity services | grep com.example 实际验证了其存在。输出服务包与我在此处详细说明的包是一致的。 - nukeforum
@Selvin 我已经更新了 DumpsterFire 项目中的 AndroidManifest,并添加了其构建脚本的完整内容。我注意到在帖子中展示的包名中出现了一个拼写错误,我已在项目和这里进行了更正。然而,更正这个错误并没有解决问题。 - nukeforum
@Pawel 感谢您的建议,不幸的是,它产生了相同的结果。 - nukeforum
显示剩余4条评论
1个回答

2
如果您正在 Android 11 上进行测试,您的问题可能是您的客户端应用程序无法看到服务应用程序。为了让此示例服务客户端在 Android 11 上找到此示例服务,我需要在客户端清单中添加一个 <queries> 元素,其中包含服务应用程序的包名:此示例服务客户端 参考此示例服务。请注意保留 HTML 标签。
<queries>
  <package android:name="com.commonsware.android.r.embed.server" />
</queries>

马克,当涉及到Android方面的事情时,你就像是某种超级英雄。非常感谢你。这正是我所需要的。 - nukeforum
这是一个关于此功能的Android文档链接,以防有人需要:https://developer.android.com/training/basics/intents/package-visibility#declare-other-apps - nukeforum
1
@nukeforum:感谢您的赞美之词!我记得当我写这些示例时,曾经为了让两个应用程序相互通信而苦思冥想了几个小时,感到非常困惑。这种行为真的很不直观。 - CommonsWare
我想这正是为什么每当新版本的Android发布时,我需要阅读所有文档的原因。:P - nukeforum
1
@nukeforum: 我就放这个链接:https://commonsware.com/R/ - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接