非静态方法问题

时间:2015-08-06 08:10:28

标签: android static-methods

通过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();

}

知道怎么解决吗?

4 个答案:

答案 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);

这不是最好的方法,但它是目前设计中最快的。