我正在尝试简单地找到一个带有MDN的设备,保存IP并杀死“网络服务发现”(NSD)一旦完成。
NSD和AsyncTask在这里冲突。
使用NSD获取IP是可行的,但如果AsyncTask不是静态的,它会警告泄漏。
如果AsyncTask是静态的,则NSD从onPostExecute()表示;
非静态字段'mNSDManager'不能从静态上下文引用
如果我将AsyncTask设置为静态但必须注释掉MNSDManager.StopServiceDiscovery(mDiscoveryListener),则如果应用程序退出,NSD仍然会从onDestroy中被杀死;在onPostExecute()中执行此操作。
使用NSD,我可以在5-15秒内获得IP,但如果AsyncTask是静态的,我不能杀死它,NSD就会非常忙。
如果我通过使AsyncTask静态化来满足它,mNsdManager会抱怨:
非静态字段'mNsdManager'不能从静态上下文引用
我可以编译的唯一方法是使AsyncTask非静态,接受可能的泄漏,或者保留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 // }
需要重写,因为我无法在没有太多错误的情况下使类getIPtoTextView成为静态的。
一旦我可以将类getIPtoTextView设置为静态,我就移动了MNSDManager.StopServiceDiscovery(mDiscoveryListener);onPause()和onDestroy()都工作得很好。
问题内容: 我有一个正在从给定的计时器开始执行后台任务的方法。我需要短暂的网络任务,所以这就是我坚持的原因。 从,我正在执行需要执行的许多操作(例如启动通知)。现在,在初始化时,我得到一条警告:“ 此字段泄漏了上下文对象。 ” 我看到了许多关于相同的问题,但是它们都与之有关。所以我的问题是,如何在我的(顶级课程)中 使用它而不泄漏它 ? 问题答案: 我有一个服务,可以从该服务从给定的计时器启动As
我的模板如下所示 现在,当我试图在注释字段“今天的天气预报是”中使用以下字符串构建模板时,velocity最终将其呈现为 我如何防止它逃脱我的角色?
各位,我使用插件cargo-maven2-plugin在Tomcat8上运行集成测试(等待tomcat8-maven-plugin) 不幸的是,当我停止容器时,我有这样一个堆栈:
本文向大家介绍Android 避免使用AsyncTask泄漏活动,包括了Android 避免使用AsyncTask泄漏活动的使用技巧和注意事项,需要的朋友参考一下 示例 注意:AsyncTask除了这里描述的内存泄漏之外,还有很多陷阱。因此,请谨慎使用此API,如果您不完全了解其含义,请完全避免使用它。有很多选择(线程,EventBus,RxAndroid等)。 一个常见的错误AsyncTask是
问题内容: 我有一个行为异常的应用程序,似乎在泄漏。经过简要的探查器调查后,大多数内存(80%)由实例保留。我怀疑终结器无法运行。 造成这种情况的常见原因似乎是终结器抛出异常。但是,该类方法的javadoc (例如参见此处)似乎自相矛盾:它指出 如果finalize方法抛出未捕获的异常,则该异常将被忽略,并且该对象的终止将终止。 但后来,它也指出 由finalize方法引发的任何异常都会导致该对象
我的遗嘱执行人服务是这样的: 实现了runnable,它的run方法具有巨大的功能,需要调用其他几个API。现在,当我在调试模式下运行代码时,任务就完成了。当我正常运行时,任务是不完整的,线程被终止。线程不是要等到所有任务都完成了吗?为什么他们没有完成任务就被解雇了?