我在Android上使用网络服务发现(NSD)在设备上宣传REST服务器.我的REST服务器包含在android.app.Service的一个实例中.
在onCreate
,我成功启动REST服务器并注册我的NSD服务.我可以在我的网络中的其他设备上看到NSD服务名称(例如我的服务).
在我onDestroy
,我停止REST服务器并取消注册NSD服务.
但是,似乎在开发时,当我推送我的应用程序的新实例(通过Eclipse)时,无法保证onDestroy
将调用该服务.这意味着我的服务仍在广告中,下次服务开始时,我最终得到我的服务(1),我的服务(2)等.
据我所知,NSD将修改服务名称以创建一个唯一的实例.我的问题是:
onDestroy
当我推送我的应用程序的新实例时,有没有办法确保我被调用?这种情况是否与用户在安装我的应用程序更新时可能遇到的情况类似?ie是否onDestroy
保证在正在运行的应用程序关闭时调用,以便可以安装该应用程序的新版本?在Android
我正在开发的应用程序中,我想使用连接做零配置网络NsdManager
.
我设法运行网络服务发现并连接到所需的网络,但停止发现后NsdManager
线程仍在运行.这导致在几次屏幕旋转之后有许多NsdManager
线程正在浏览连接的情况.
当任何网络可用时,设备会尝试多次同步,因此NsdManager
尽管停止服务发现,每个网络仍处于活动状态.
贝娄是我的代码:
package dtokarzewsk.nsdservicetest;
import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.util.Log;
import java.net.InetAddress;
public class NsdTest {
private static final String NSD_SERVICE_NAME = "TestService";
private static final String NSD_SERVICE_TYPE = "_http._tcp.";
private int mPort;
private InetAddress mHost;
private Context mContext;
private NsdManager mNsdManager;
private android.net.nsd.NsdManager.DiscoveryListener mDiscoveryListener;
private android.net.nsd.NsdManager.ResolveListener mResolveListener;
public NsdTest(Context context) {
mContext = context;
}
public void startListening() {
initializeResolveListener();
initializeDiscoveryListener();
mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个类来发现网络上的服务.我曾尝试使用Android的NSD,它确实发现服务很好,但它只支持16级及以上的API级别,而且我似乎无法检索服务信息中的txtRecord字段(由于某种原因它返回null).原来这是一个已知问题......
所以现在我正在尝试使用jmDNS,它似乎根本找不到服务.这是我的班级(我正在使用AndroidAnnotations框架)MDnsHelper:
@EBean
public class MDnsHelper implements ServiceListener {
public static final String SERVICE_TYPE = "_http._tcp.local";
Activity activity;
private JmDNS jmdns;
private MulticastLock multicastLock;
WifiManager wm;
InetAddress bindingAddress;
boolean isDiscovering;
public void init(Activity activity) {
this.activity = activity;
isDiscovering = false;
wm = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
multicastLock = wm.createMulticastLock(activity.getPackageName());
multicastLock.setReferenceCounted(false);
}
@Background
public void startDiscovery() {
if (isDiscovering)
return;
System.out.println("starting...");
multicastLock.acquire();
try {
System.out.println("creating jmdns");
jmdns = JmDNS.create();
System.out.println("jmdns created");
} catch (IOException e) {
e.printStackTrace(); …
Run Code Online (Sandbox Code Playgroud) 发现服务会导致系统崩溃.我正在尝试的发现类型是
"_http._tcp."
这是日志.
D/NsdService(13310): Discover services E/AndroidRuntime(13310): *** FATAL EXCEPTION IN SYSTEM PROCESS: NsdService E/AndroidRuntime(13310): java.lang.NullPointerException E/AndroidRuntime(13310): at com.android.server.NsdService$ClientInfo.access$1200(NsdService.java:801) E/AndroidRuntime(13310): at com.android.server.NsdService$NsdStateMachine$EnabledState.requestLimitReached(NsdService.java:244) E/AndroidRuntime(13310): at com.android.server.NsdService$NsdStateMachine$EnabledState.processMessage(NsdService.java:292) E/AndroidRuntime(13310): at com.android.internal.util.StateMachine$SmHandler.processMsg(StateMachine.java:905) E/AndroidRuntime(13310): at com.android.internal.util.StateMachine$SmHandler.handleMessage(StateMachine.java:760) E/AndroidRuntime(13310): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(13310): at android.os.Looper.loop(Looper.java:137) E/AndroidRuntime(13310): at android.os.HandlerThread.run(HandlerThread.java:60)
我用来开始发现的代码是
NsdManager nsd = (NsdManager) getSystemService(Context.NSD_SERVICE); nsd.discoverServices("_http._tcp.", NsdManager.PROTOCOL_DNS_SD, discoveryListener);
当我跑步时,我的手机每次都会重启.我想这是Android 4.2.2上的一个错误
我的应用程序本质上是一个后台服务,需要偶尔注册一个NSD
服务(Bonjour
服务),以便能够发现由主后台服务运行的套接字服务器(也就是由app运行).
如果我正确阅读Android Bonjour服务文档,这就是您启动Bonjour
服务的方式(缩写为简洁):
mNsdManager = Context.getSystemService(Context.NSD_SERVICE);
mDiscoveryListener = new NsdManager.DiscoveryListener()
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
Run Code Online (Sandbox Code Playgroud)
......这就是你如何阻止它:
mNsdManager.unregisterService(mRegistrationListener);
Run Code Online (Sandbox Code Playgroud)
在这里,我无法解决这个问题:如果主服务突然Bonjour
崩溃,那么在崩溃时注册的任何服务都会继续运行,即使它不再具有目的(它帮助发现的套接字服务器不是更长的).
Bonjour
当主服务重新启动时,我无法事件清理僵尸服务,因为mRegistrationListener
最初注册的服务也不再存在.
我怀疑我采取了错误的方法:Bonjour
在主服务崩溃后,我如何确保不会留下一堆乱七八糟的僵尸服务?