Android:从静态 Handler 类调用非静态方法
Posted
技术标签:
【中文标题】Android:从静态 Handler 类调用非静态方法【英文标题】:Android: Calling non-static methods from a static Handler class 【发布时间】:2012-08-03 10:07:42 【问题描述】:鉴于此代码:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener
public static final int MESSAGE_NOT_CONNECTED = 1;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
// -------------------------------------------------
public final void setStatus(int Rid)
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(Rid);
// -------------------------------------------------
static Handler mHandler = new Handler()
@Override
public void handleMessage(Message msg)
switch (msg.what)
case MESSAGE_NOT_CONNECTED:
setStatus(R.string.title_not_connected);
break;
我收到编译错误:无法对非静态方法 setStatus(int) 进行静态引用 ...
这是有道理的,因为 setStatus() 中的 getActionBar() 是一个非静态方法。
由于警告,我将 Handler 类设为静态:此 Handler 类应该是静态的,否则可能会发生泄漏。
问题:如何从静态处理程序中正确访问 setStatus() 方法?
编辑:新的处理程序代码就是答案。
static class hHandler extends Handler
private final WeakReference<MainActivity> mTarget;
hHandler(MainActivity target)
mTarget = new WeakReference<MainActivity>(target);
@Override
public void handleMessage(Message msg)
MainActivity target = mTarget.get();
If(target == null)
return;
switch (msg.what)
case MESSAGE_NOT_CONNECTED:
target.setStatus(R.string.title_not_connected);
break;
【问题讨论】:
***.com/q/11407943/844882 @Alex Lockwood 提供的链接指向另一个来自 Romain Guy 的链接,它帮助我理解了弱引用:静态与非静态内部类 link。我可以回答我自己的问题,但我还不能发布。 我回答了这个问题(因为你显然还不能发布它......):P 【参考方案1】:尝试使用WeakReference
,如article 中所述。
【讨论】:
这就是答案。我用更改编辑了原始帖子。感谢您的发帖,亚历克斯。 @Alex Lockwood 那篇文章很好,但它没有解释如何从静态处理程序中获取上下文。我正在使用 Toast.makeText(getApplicationContext(), dataString, Toast.LENGTH_SHORT).show();既然 Handler 是静态的,那么 getApplicationContext() 就没有意义了。如果这很重要,我的处理程序在服务中。 @DavidDoria 给Handler
一个构造函数,它接受Context
作为参数,然后持有对该Context
的弱引用。【参考方案2】:
由于您现在使用的是WeakReference
,因此mTarget.get()
可能会返回null
。在您编辑的代码中,您没有在执行 target.setStatus(R.string.title_not_connected)
之前检查 target
是否为 null
。因此,如果弱引用对象已被 GC 处理,这可能会抛出 NullPointerException
。
【讨论】:
【参考方案3】:在我调用的活动的 onDestroy 方法中:
this.myHandler.removeCallbacksAndMessages(null);
这并没有消除“这个处理程序类应该是静态的,否则可能会发生泄漏”的警告,但我相信它会破坏消息从而阻止泄漏。我的处理程序类是我活动的内部非静态类。我的活动有一个 MyHandler myHandler 的实例。
当我这样做时,不会调用处理程序的 handleMessage 方法,我认为这意味着包含处理程序的消息已被销毁,其中包含对活动的引用。我对 cmets 持开放态度,因为我没有使用任何泄漏测试工具对其进行测试。这是我复制这个想法的地方:http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html 回答者:Cyril 2013 年 1 月 15 日上午 7:50
【讨论】:
以上是关于Android:从静态 Handler 类调用非静态方法的主要内容,如果未能解决你的问题,请参考以下文章
Android Threading:这个 Handler 类应该是静态的,否则可能会发生泄漏[重复]