Java 接收器作为 Android 中的内部类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3608955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Receiver as inner class in Android
提问by Kunal P.Bharati
In my code there is an inner class that extends BroadcastReceiver
.
在我的代码中有一个内部类扩展BroadcastReceiver
.
And I have added the following line to the AndroidManifest.xml
:
我已经添加了以下行AndroidManifest.xml
:
<receiver android:name="OuterClass$InnerClass android:enabled="true"/>
But I am receiving the following error:
但我收到以下错误:
unable to instantiate receiver org.example.test.OuterClass$InnerClass
无法实例化接收器 org.example.test.OuterClass$InnerClass
How can I solve this issue ?
我该如何解决这个问题?
回答by DonGru
Could it be that there is just a dot and a closing quote missing? Like
可能只是缺少一个点和一个结束语吗?喜欢
<receiver android:name=".OuterClass$InnerClass" android:enabled="true"/>
回答by BalusC
The $
notation doesn't denote an inner class, but a static nested class. So there are in theory 2 ways to solve this particular problem:
该$
符号不表示内部类,而是表示静态嵌套类。所以理论上有两种方法可以解决这个特定问题:
Denote it as a real inner class, i.e.
OuterClass.InnerClass
(not sure though if Android will eat that since the instantiation of an inner class is pretty more complex than just doingClass#newInstance()
.Declare the class to be a static nested class instead, i.e. add
static
toclass InnerClass {}
. This way theOuterClass$InnerClass
must be able to create a new instance out of it.
将其表示为真正的内部类,即
OuterClass.InnerClass
(不确定 Android 是否会吃掉它,因为内部类的实例化比仅执行Class#newInstance()
.将该类声明为静态嵌套类,即添加
static
到class InnerClass {}
. 这样,OuterClass$InnerClass
必须能够从中创建一个新实例。
If that doesn't solve the problem, then apparently Android simply doesn't eat it that way. I'd just extract it into its own standalone class then.
如果这不能解决问题,那么显然 Android 根本不会那样吃。我只是将它提取到它自己的独立类中。
See also:
也可以看看:
- Java tutorial - Nested classes
- Answer with code example how to instantiate an inner or static nested class using reflection(as Android should be doing "under the covers")
- Java 教程 - 嵌套类
- 用代码示例回答如何使用反射实例化内部或静态嵌套类(因为 Android 应该“在幕后”做)
回答by Bert Regelink
An (non-static) inner classcannot be instantiated by Android via the AndroidManifest.xml (Android developer documentation on BroadcastReceiver):
Android 无法通过 AndroidManifest.xml(关于 BroadcastReceiver 的 Android 开发人员文档)实例化(非静态)内部类:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically publish an implementation through the tag in your AndroidManifest.xml.
您可以使用 Context.registerReceiver() 动态注册此类的实例,也可以通过 AndroidManifest.xml 中的标记静态发布实现。
So you can dynamically register the receiver. In my application I wanted to do the same for using Google's Cloud to Device Messaging (C2DM) and my original AndroidManifest.xml contained:
所以你可以动态注册接收器。在我的应用程序中,我想对使用 Google 的 Cloud to Device Messaging (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>
I removed that receiversection and dynamically registered the receiver as follows:
我删除了该接收器部分并按如下方式动态注册接收器:
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
{
...
}
}
回答by Gavriel
This is what worked for me:
这对我有用:
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:
AndroidManifest.xml:
<receiver android:name=".OuterClass$OuterClassConnector$InnerStaticClass" />
回答by River
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:
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. Register receiver in manifest.xml :
2. 在 manifest.xml 中注册接收器:
<receiver android:name=".XXService$XXReceiver" android:enabled="true"/>
回答by MBH
you dont need to use $... If you get warning for a class which is not actually an inner class, it's because you are using uppercase characters in your package name, which is not conventional.
你不需要使用$... 如果你收到一个实际上不是内部类的类的警告,那是因为你在包名中使用了大写字符,这不符合惯例。
I tried also to change only the first letter of the package name to be lower case, the warning and error disappeared.
我也尝试将包名的第一个字母改为小写,警告和错误消失了。