我试图简单地找到具有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()都工作良好。

10-06 09:01