我试图简单地找到一个带有mDNS的设备,保存IP并在完成后终止“网络服务发现”(NSD) .

NSD和AsyncTask在这里发生冲突 .

使用NSD获取IP有效,但如果AsyncTask不是静态的,则会发出泄漏警告 .

如果AsyncTask是静态的,那么NSD会从onPostExecute();
Non-static field 'mNsdManager' cannot be referenced from a static context

如果应用程序退出,如果我使AsyncTask静态但是必须在onPostExecute()中注释 mNsdManager.stopServiceDiscovery( mDiscoveryListener); 来执行此操作,NSD仍然会从onDestroy中被杀死 .

使用 NSD 我在5-15秒内获得IP,但如果AsyncTask是静态的,我不能杀死NSD .

如果我通过使其静态 mNsdManager 抱怨来满足AsyncTask:
Non-static field 'mNsdManager' cannot be referenced from a static context

我可以编译的唯一方法是使AsyncTask非静态并接受可能的泄漏 -OR- 保留AsyncTask静态并注释掉onPostExecute()中的KILL行 .

2错误标记在下面的代码中 .

使用基于Android事件的AsyncTask似乎是最好的方法,但这是正确的方法吗?

我怎么能杀死 mNsdManager 并仍然使 AsyncTask 静态来阻止泄漏?

package com.fib.onacci.fibonacci;

    private static final String TAG = "CLOCK : ";
    private TextView mIP_address;

    // NSD members, Allows app to discover the "fibonacci.local"
    // Reference: 
    // http://developer.android.com/training/connect-devices-wirelessly/nsd.html

          private static NsdManager mNsdManager;
          private static NsdManager.DiscoveryListener mDiscoveryListener;
          private NsdManager.ResolveListener mResolveListener;
          private NsdServiceInfo mServiceInfo;
          public String mRPiAddress;
          public static String IPaddress ="-"; // something to look for change
          private static final String SERVICE_TYPE = "_http._tcp."; 

        public class MainActivity extends AppCompatActivity {

        private static final String TAG = "CLOCK: ";

          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);

              new getIPtoTextView().execute();  // start the AsyncTask

              // setup nDNS and find IP
              mRPiAddress = "";
              IPaddress = "-";
              mNsdManager = (NsdManager)(getApplicationContext().getSystemService(Context.NSD_SERVICE));
              initializeResolveListener();
              initializeDiscoveryListener();
              mNsdManager.discoverServices( SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);

          }  // END onCreate

         // NSD start - Network discovery

ERROR This AsyncTask class should be static or leaks might occur 
          A static field will leak contexts.   

          private static class getIPtoTextView extends AsyncTask {
              /** part of nDiscovery - find clock and kill discovery service
               *  `doInBackground` is run on a separate, background thread
               */
              @Override
              protected Void doInBackground(Void... params) {
                  String mloop = IPaddress;
                  while ( mloop.equals("-")) {
                      mloop = IPaddress;
                      try {
                          Thread.sleep(100);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  Log.i( TAG, "doInBackground - IP Found - " + mloop );
                  return null;
              }

              /** part of nDiscovery
               * `onPostExecute` is run after `doInBackground`, and it's
               * run on the main/ui thread, so you it's safe to update ui
               * components from it. (this is the correct way to update ui
               * components.)
               */
              @Override
              protected void onPostExecute(Void param) {
                Log.i( TAG, "onPostExecute - IP Found - " + IPaddress );

                  TextView IP_Window = findViewById(R.id.IP_address); 
                  IP_Window.setText( IPaddress);  // post IP address to TextView

ERROR Non-static field 'mNsdManager' cannot be referenced from a static context
                  mNsdManager.stopServiceDiscovery( mDiscoveryListener);                     // kill mDiscoveryListener
              }
          }  // end asyncTask class

          private void initializeDiscoveryListener() {

            mDiscoveryListener = new NsdManager.DiscoveryListener() { // Listener

                  @Override
                  public void onDiscoveryStarted(String regType) {
                  }

                  @Override
                  public void onServiceFound(NsdServiceInfo service) { // service found!
                      String name = service.getServiceName();
                      String type = service.getServiceType();

                      if ( type.equals(SERVICE_TYPE) && name.contains("Fibonacci")) {
                          Log.i( TAG, "\n\tNSD Service Found @ ' " + name + "'");
                          mNsdManager.resolveService(service, mResolveListener);
                      }
                  }

                  @Override
                  public void onServiceLost(NsdServiceInfo service) {  
                  }

                  @Override
                  public void onDiscoveryStopped(String serviceType) {
                  }

                  @Override
                  public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                      mNsdManager.stopServiceDiscovery(this);
                  }

                  @Override
                  public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                      mNsdManager.stopServiceDiscovery(this);
                  }
              };
          }

          private void initializeResolveListener() {
              mResolveListener = new NsdManager.ResolveListener(){

                  @Override
                  public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                      Log.i( TAG, "\n\t\tNSD Resolve failed " + errorCode + "\n\n" );
                  }

                  @Override
                  public void onServiceResolved( NsdServiceInfo serviceInfo ) {
                      mServiceInfo = serviceInfo;
                      InetAddress host = mServiceInfo.getHost();
                       IPaddress = host.getHostAddress();
                      mRPiAddress = IPaddress;
                      Log.i( TAG, "\n\t\tNSD Resolved address = " + IPaddress + "\n\n" );
                    }
                };
            }

            @Override
            protected void onPause() {
                super.onPause();
                if ( mDiscoveryListener != null) {
                    mNsdManager.stopServiceDiscovery( mDiscoveryListener);
                }
            }

            @Override
            protected void onResume() {
                super.onResume();
                if ( mDiscoveryListener != null) {
                  mIP_address.setText( R.string.searching );  // TextView - Searching -
                    try {
                        Thread.sleep( 1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    initializeDiscoveryListener();
                }
            }

            @Override
            protected void onDestroy() {
                super.onDestroy();
                mNsdManager.stopServiceDiscovery( mDiscoveryListener);  
            }
        // NSD end //
      }