Я пытаюсь просто найти устройство с mDNS, сохранить IP-адрес и завершить «Обнаружение сетевых служб» (NSD).
NSD и AsyncTask находятся в конфликте.
Получение IP с помощью NSD работает, но если AsyncTask не является статическим, оно предупреждает о утечках.
Если AsyncTask является статическим, NSD сообщает из onPostExecute ();
Нестатическое поле 'mNsdManager'нельзя ссылаться из статического контекста
NSD по-прежнему уничтожается из onDestroy, если приложение завершается, если я делаю AsyncTask статическим, но приходится комментировать mNsdManager.stopServiceDiscovery (mDiscoveryListener); в onPostExecute (), чтобы сделать это.
С NSD Я получаю IP через 5-15 секунд, но NSD остается серьезно занятым, если я не могу убить его, если AsyncTask статичен.
Если я удовлетворяю AsyncTask, делая его статическим mNsdManager жалуется:
Нестатическое поле 'mNsdManager' нельзя ссылаться из статического контекста
Единственный способ, которым я могу скомпилироватьs делает AsyncTask нестатичным и принимает возможные утечки -OR- , оставляя AsyncTask статичным и закомментирует строку KILL в onPostExecute ().
2 ОШИБКИ, отмеченные в коде ниже.
С Android Event на основе 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
<b>ERROR This AsyncTask class should be static or leaks might occur
A static field will leak contexts.</b>
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
<b>ERROR Non-static field 'mNsdManager' cannot be referenced from a static context</b>
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 //
}