我试图简单地找到具有mDNS的设备,保存IP,并在完成后杀死“网络服务发现”(NSD)。
NSD和AsyncTask在这里发生冲突。
使用NSD获取IP是可行的,但是如果AsyncTask不是静态的,则会警告泄漏。
如果AsyncTask是静态的,则NSD从onPostExecute();开始。
无法从静态上下文中引用非静态字段“ mNsdManager”
如果我将AsyncTask设为静态,但必须将mNsdManager.stopServiceDiscovery(mDiscoveryListener)注释掉,则App退出时,NSD仍会从onDestroy中杀死。在onPostExecute()中做到这一点。
使用NSD,我可以在5到15秒内获得IP,但是如果AsyncTask是静态的,如果我无法杀死它,NSD就会非常忙。
如果我通过将其设为静态来满足AsyncTask的要求,则mNsdManager会抱怨:
无法从静态上下文中引用非静态字段“ mNsdManager”
我可以编译的唯一方法是使AsyncTask为非静态并接受可能的泄漏-或-使AsyncTask保持静态并注释掉onPostExecute()中的KILL行。
在以下代码中标记了2个错误。
使用基于Android事件的AsyncTask似乎是最好的方法,但这是正确的方法吗?
如何杀死mNsdManager并使AsyncTask保持静态以阻止泄漏?
软件包com.fib.onacci.fibonacci;
私有静态最终String TAG =“ CLOCK:”;
私人TextView mIP_address;
// NSD成员,允许应用发现“ fibonacci.local”
//参考:
// http://developer.android.com/training/connect-devices-wirelessly/nsd.html
私有静态NsdManager mNsdManager;
私有静态NsdManager.DiscoveryListener mDiscoveryListener;
私有NsdManager.ResolveListener mResolveListener;
私有NsdServiceInfo mServiceInfo;
公共字符串mRPiAddress;
公共静态字符串IPaddress =“-”; //寻找变化的东西
私有静态最终字符串SERVICE_TYPE =“ _http._tcp。”;
公共类MainActivity扩展了AppCompatActivity {
私有静态最终String TAG =“ CLOCK:”;
@Override
受保护的void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
新的getIPtoTextView()。execute(); //启动AsyncTask
//设置nDNS并找到IP
mRPiAddress =“”;
IPaddress =“-”;
mNsdManager =(NsdManager)(getApplicationContext()。getSystemService(Context.NSD_SERVICE));
initializeResolveListener();
initializeDiscoveryListener();
mNsdManager.discoverServices(SERVICE_TYPE,NsdManager.PROTOCOL_DNS_SD,mDiscoveryListener);
} //结束onCreate
// NSD启动-网络发现
错误此AsyncTask类应该是静态的,否则可能会发生泄漏
静态字段将泄漏上下文。
私有静态类getIPtoTextView扩展了AsyncTask {
/ ** nDiscovery的一部分-查找时钟并终止发现服务
*`doInBackground`在单独的后台线程上运行
* /
@Override
protected Void doInBackground(Void ... params){
字符串mloop = IPaddress;
while(mloop.equals(“-”)){
mloop = IP地址;
尝试{
Thread.sleep(100);
} catch(InterruptedException e){
e.printStackTrace();
}
}
Log.i(TAG,“ doInBackground-找到IP-” + mloop);
返回null;
}
/ ** nDiscovery的一部分
*`onPostExecute`在`doInBackground`之后运行,它是
*在主/ ui线程上运行,因此您可以安全地更新ui
*组件。 (这是更新ui的正确方法
* 组件。)
* /
@Override
受保护的void onPostExecute(Void param){
Log.i(TAG,“ onPostExecute-找到IP-” + IPaddress);
TextView IP_Window = findViewById(R.id.IP_address);
IP_Window.setText(IPaddress); //将IP地址发布到TextView
错误不能从静态上下文中引用非静态字段“ mNsdManager”
mNsdManager.stopServiceDiscovery(mDiscoveryListener); //杀死mDiscoveryListener
}
} //结束asyncTask类
私人void initializeDiscoveryListener(){
mDiscoveryListener = new NsdManager.DiscoveryListener(){//侦听器
@Override
公共无效onDiscoveryStarted(String regType){
}
@Override
public void onServiceFound(NsdServiceInfo service){//找到服务!
字符串名称= service.getServiceName();
字符串类型= service.getServiceType();
if(type.equals(SERVICE_TYPE)&& name.contains(“ Fibonacci”)){
Log.i(TAG,“ \ n \ tNSD服务已找到@'” +名称+“'”);
mNsdManager.resolveService(service,mResolveListener);
}
}
@Override
公共无效onServiceLost(NsdServiceInfo服务){
}
@Override
公共无效onDiscoveryStopped(String serviceType){
}
@Override
公共无效onStartDiscoveryFailed(String serviceType,int errorCode){
mNsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String serviceType,int errorCode){
mNsdManager.stopServiceDiscovery(this);
}
};
}
私人void initializeResolveListener(){
mResolveListener =新的NsdManager.ResolveListener(){
@Override
公共无效onResolveFailed(NsdServiceInfo serviceInfo,int errorCode){
Log.i(TAG,“ \ n \ t \ tNSD解决失败” + errorCode +“ \ n \ n”);
}
@Override
公共无效onServiceResolved(NsdServiceInfo serviceInfo){
mServiceInfo = serviceInfo;
InetAddress主机= mServiceInfo.getHost();
IP地址= host.getHostAddress();
mRPiAddress = IP地址;
Log.i(TAG,“ \ n \ t \ tNSD解析地址=” + IPaddress +“ \ n \ n”);
}
};
}
@Override
受保护的void onPause(){
super.onPause();
如果(mDiscoveryListener!= null){
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
}
@Override
受保护的void onResume(){
super.onResume();
如果(mDiscoveryListener!= null){
mIP_address.setText(R.string.searching); // TextView-搜索-
尝试{
Thread.sleep(1500);
} catch(InterruptedException e){
e.printStackTrace();
}
initializeDiscoveryListener();
}
}
@Override
受保护的void onDestroy(){
super.onDestroy();
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
// NSD结束//
}
最佳答案
需要重写,因为没有太多错误我无法使类getIPtoTextView静态。
一旦我可以使类getIPtoTextView静态,我就搬了
mNsdManager.stopServiceDiscovery(mDiscoveryListener);到onPause()和onDestroy()都工作良好。