接收者作为Android中的内部类

时间:2010-08-31 12:23:33

标签: java android broadcastreceiver

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

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

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

但我收到以下错误:

  

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

我该如何解决这个问题?

6 个答案:

答案 0 :(得分:32)

Android无法通过AndroidManifest.xml(inner class)实例化(非静态)Android developer documentation on BroadcastReceiver

  

您可以使用动态注册此类的实例   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
    {
        ...
    }
}

答案 1 :(得分:17)

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

  1. 将它表示为一个真正的内部类,即OuterClass.InnerClass(不确定Android是否会吃掉它,因为内部类的实例化比执行Class#newInstance()要复杂得多。< / p>

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

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

    另见:

答案 2 :(得分:6)

可能只是缺少一个点和一个收盘报价吗?像

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

答案 3 :(得分: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" />

答案 4 :(得分:0)

我刚遇到同样的问题。

我有一项与许多活动进行交流的服务,我的服务中也有一个接收器作为内部类。当接收者得到消息时,它必须调用服务方法。所以它继续这样:

<强> 1。服务代码:

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。在manifest.xml中注册接收者:

<receiver android:name=".XXService$XXReceiver" android:enabled="true"/>

答案 5 :(得分:0)

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

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