21

在我的代码中有一个扩展的内部类BroadcastReceiver

我已将以下行添加到AndroidManifest.xml

<receiver android:name="OuterClass$InnerClass android:enabled="true"/>

但我收到以下错误:

无法实例化接收器 org.example.test.OuterClass$InnerClass

我该如何解决这个问题?

4

6 回答 6

33

Android 无法通过 AndroidManifest.xml 实例化(非静态)内部类( BroadcastReceiver 上的 Android 开发人员文档):

您可以使用 Context.registerReceiver() 动态注册此类的实例,也可以通过 AndroidManifest.xml 中的标记静态发布实现。

所以你可以动态注册接收者。在我的应用程序中,我想为使用 Google 的云到设备消息传递 (C2DM) 做同样的事情,我原来的 AndroidManifest.xml 包含:

<application...>
    <receiver android:name=".MyC2dmReceiver" android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="com.example.myapp" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="com.example.myapp" />
        </intent-filter>
    </receiver>
</application>

我删除了该接收器部分并动态注册了接收器,如下所示:

public class AndroidService extends IntentService
{
    ... 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.google.android.c2dm.intent.RECEIVE");
        filter.addAction("com.google.android.c2dm.intent.REGISTRATION");
        filter.addCategory("com.example.myapp");
        this.registerReceiver(new MyC2dmReceiver(), filter, "com.google.android.c2dm.permission.SEND", null);
        return super.onStartCommand(intent,flags,startId);
    }

    public class MyC2dmReceiver extends BroadcastReceiver
    {
        ...
    }
}
于 2012-06-01T14:13:21.600 回答
18

$符号不表示内部类,而是静态嵌套类。所以理论上有两种方法可以解决这个特定问题:

  1. 将其表示为真正的内部类,即OuterClass.InnerClass(不确定 Android 是否会吃掉它,因为内部类的实例化比仅仅做Class#newInstance().

  2. 将类声明为静态嵌套类,即添加staticclass InnerClass {}. 这样,OuterClass$InnerClass必须能够从中创建一个新实例。

如果这不能解决问题,那么显然 Android 根本不会那样吃。我只是将它提取到它自己的独立类中。

也可以看看:

于 2010-08-31T14:29:01.213 回答
7

可能只是缺少一个点和一个结束引号吗?喜欢

<receiver android:name=".OuterClass$InnerClass" android:enabled="true"/>
于 2010-08-31T12:50:36.277 回答
4

这对我有用:

public class OuterClass {
    public static class InnerStaticClass extends BroadcastReceiver {
        @Override
        public void onReceive(final Context context, final Intent intent) {
            final Location location = (Location) intent.getExtras().get(LocationClient.KEY_LOCATION_CHANGED);
        }
    }
}

AndroidManifest.xml:

    <receiver android:name=".OuterClass$OuterClassConnector$InnerStaticClass" />
于 2014-10-13T18:38:22.487 回答
0

I've just met the same problem.

I have a service to communicate with many activities, and I also have a receiver in my service as inner class. when the receiver get message ,it has to call the method of service. so it goes on like this :

1. Service code:

public class XXService extends Service{

     // I want the inner receiver call the methd of XXService,
    // so I have to write this constructor like this.

    private XXService instance;
    public XXService(){instance = this;}
    public XXService getInstance(){
       return instance;
    }
    public void sayHello(){
    }
    public static class XXReceiver extends BroadcastReceiver{

        onReceive(......){
            XXService.getInstance.sayHello();
        } 
   }
}

2. Register receiver in manifest.xml :

<receiver android:name=".XXService$XXReceiver" android:enabled="true"/>
于 2015-01-27T06:50:19.807 回答
0

你不需要使用$ ...如果你收到一个实际上不是内部类的类的警告,那是因为你在包名中使用了大写字符,这不是传统的。

我还尝试仅将包名称的第一个字母更改为小写,警告和错误消失了。

于 2015-10-07T07:06:42.643 回答