通过android studio运行代码检查后,它突出显示MainHandler应该是静态的。我将课程移至静态,但现在它抱怨了 "非静态方法remainingSecondsChanged(int)无法从静态上下文引用"
public class CountDownView extends FrameLayout {
private static void remainingSecondsChanged(int newVal) {
mRemainingSecs = newVal;
if (mListener != null) {
mListener.onRemainingSecondsChanged(mRemainingSecs);
}
if (newVal == 0) {
// Countdown has finished.
setVisibility(View.INVISIBLE);
if (mListener != null) {
mRemainingSecondsView.setText(null);
mRemainingSecondsView.setBackgroundResource(R.drawable.bracket_view_finder);
mListener.onCountDownFinished();
}
} else {
Locale locale = getResources().getConfiguration().locale;
String localizedValue = String.format(locale, "%d", newVal);
mRemainingSecondsView.setText(localizedValue);
// Schedule the next remainingSecondsChanged() call in 1 second
mHandler.sendEmptyMessageDelayed(SET_TIMER_TEXT, 1000);
}
}
public void startCountDown(int sec) {
if (sec < 0) {
return;
}
if (sec == 0) {
cancelCountDown();
}
mRemainingSecondsView.setBackgroundResource(R.drawable.bracket_count_down);
setVisibility(View.VISIBLE);
remainingSecondsChanged(sec);
}
private static class MainHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (message.what == SET_TIMER_TEXT) {
remainingSecondsChanged(mRemainingSecs - 1);
}
}
}
private static final MainHandler mHandler = new MainHandler();
}
知道怎么解决吗?
答案 0 :(得分:2)
这篇StackOverflow帖子here 解释为什么内部类应该是静态的,这就是为什么代码分析器会抱怨它的原因,假设你想要从你的内容中访问包含类的成员内部类,你可以使它非静态
答案 1 :(得分:2)
首先......为什么工作室会显示该消息?
<强>背景强>
每个Handler
都与Thread
相关联,同一个Handler
上的所有Thread
个对象共享一个共同的Looper
对象,在那里发布和读取他们的消息。事情是......当这些对象非静态时......非静态内部类对其外部类进行隐式引用。因此Handler
将保留对您Activity
的引用,如果此Handler
有延迟消息,则在处理此消息之前,您的Activity
将无法进行垃圾回收
您可以详细了解here。
<强>解决方案强>
至于你的问题。你已经做过的第一件事就是让你的Handler
成为static
内部阶级。现在,为您的外部课程创建WeakReference
(可能是Activity
,或者我相信您的CountDownView
)。
现在尝试将Handler
更改为类似的内容(而不是Activity
,您可以引用CountDownView
):
private static class MainHandler extends Handler {
private final WeakReference<YourActivity> mActivity;
public MainHandler(YourActivity activity) {
mActivity = new WeakReference<YourActivity>(activity);
}
@Override
public void handleMessage(Message message) {
YourActivity activity = mActivity.get();
if (activity != null) {
if (message.what == SET_TIMER_TEXT) {
activity.remainingSecondsChanged(mRemainingSecs - 1);
}
}
}
}
并像这样实例化:
// this is a reference to your Activity, or your CountDownView, wherever your method is.
private final MainHandler mHandler = new MainHandler(this);
答案 2 :(得分:0)
我不是android程序员,但可能不是创建扩展Handler的内部类而不是像这样创建私有字段:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
//call your non static method here
}
}
答案 3 :(得分:0)
更改MainHandler的构造函数以接收回调接口
public MainHandler(Callback cb){
this.mCallBack = cb;
}
然后在handleMessage中调用回调接口来执行方法
public void handleMessage(Message message) {
if (message.what == SET_TIMER_TEXT) {
mCallBack.someMethod();1);
}
}
在片段声明接口
public interface Callback
{
void someMethod();
}
让你的片段实现它。
private final MainHandler mHandler = new MainHandler(this);
然后在实施电话
remainingSecondsChanged(mRemainingSecs - 1);
这不是最好的方法,但它是目前设计中最快的。