Убить обнаружение сетевых служб из AsyncTask, когда это сделано без утечек
Я пытаюсь просто найти устройство с 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' нельзя ссылаться из статического контекста.
Единственный способ, которым я могу скомпилировать, - сделать AsyncTask нестатичным и принять возможные утечки. ИЛИ оставить AsyncTask статическим и закомментировать строку KILL в onPostExecute ().
2 ОШИБКИ отмечены в коде ниже.
AsyncTask на базе Android Event кажется лучшим, но правильный ли это путь?
Как я могу убить mNsdManager и при этом сделать AsyncTask статическим, чтобы блокировать утечки?
пакет com.fib.onacci.fibonacci; приватная статическая финальная строка TAG = "CLOCK: "; частный TextView mIP_address; // Члены NSD, позволяет приложению обнаруживать "fibonacci.local" // Ссылка: // http://developer.android.com/training/connect-devices-wirelessly/nsd.html private static NsdManager mNsdManager; частный статический NsdManager.DiscoveryListener mDiscoveryListener; частный NsdManager.ResolveListener mResolveListener; частный NsdServiceInfo mServiceInfo; public String mRPiAddress; public static String IPaddress ="-"; // что-то искать для изменения приватной статической final final String SERVICE_TYPE = "_http._tcp."; открытый класс MainActivity extends AppCompatActivity {частная статическая конечная строка String TAG = "CLOCK: "; @Override protected void onCreate(Bundle saveInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_main); новый getIPtoTextView().execute(); // запускаем AsyncTask // настраиваем nDNS и находим IP mRPiAddress = ""; IP-адрес = "-"; mNsdManager = (NsdManager)(getApplicationContext().getSystemService(Context.NSD_SERVICE)); initializeResolveListener(); initializeDiscoveryListener(); mNsdManager.discoverServices( SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); } // END onCreate // NSD start - обнаружение сети ОШИБКА Этот класс AsyncTask должен быть статическим, иначе могут возникнуть утечки. Статическое поле будет пропускать контексты. закрытый статический класс getIPtoTextView расширяет AsyncTask { /** часть nDiscovery - служба обнаружения часов и уничтожения * `doInBackground` запускается в отдельном фоновом потоке */ @Override protected Void doInBackground(Void... params) { String mloop = Айпи адрес; while ( mloop.equals("-")) { mloop = IP-адрес; попробуй { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } Log.i( TAG, "doInBackground - IP Found - " + mloop); вернуть ноль; } /** часть nDiscovery * `onPostExecute` запускается после` doInBackground` и * запускается в потоке main/ui, поэтому вы можете безопасно обновлять компоненты ui * из него. (это правильный способ обновления компонентов пользовательского интерфейса *.) */ @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); // отправить IP-адрес в TextView ERROR Нестатическое поле 'mNsdManager' не может быть использовано из статического контекста mNsdManager.stopServiceDiscovery( mDiscoveryListener); // kill mDiscoveryListener } } // конец частного класса asyncTask void initializeDiscoveryListener() { mDiscoveryListener = new NsdManager.DiscoveryListener() { // Listener @Override public void onDiscoveryStarted(String regType) { } @Override public void serviceSoundServiceService // сервис найден! 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(сервис, mResolveListener); } } @Override public void onServiceLost(служба NsdServiceInfo) { } @Override public void onDiscoveryStopped(String serviceType) { } @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { mNsdManager.stopServiceDis; } @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 Resol", Resol n\n"); } @Override public void onServiceResolved( NsdServiceInfo serviceInfo) { mServiceInfo = serviceInfo; InetAddress host = mServiceInfo.getHost(); IPaddress = host.getHostAddress(); mRPiAddress = IP-адрес; 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 - Поиск - try { Thread.sleep( 1500); } catch (InterruptedException e) { e.printStackTrace(); } initializeDiscoveryListener(); } } @Override protected void onDestroy() { super.onDestroy(); mNsdManager.stopServiceDiscovery( mDiscoveryListener); } // конец NSD // }
0 ответов
Потребовалось переписать, потому что я не мог сделать класс getIPtoTextView статическим без слишком большого количества ошибок.
Как только я смог сделать класс getIPtoTextView статическим, я переместил mNsdManager.stopServiceDiscovery( mDiscoveryListener); to onPause() и onDestroy() все работало нормально.