【问题标题】:Function is working in OnClick but not in OnCreate()函数在 OnClick 中有效,但在 OnCreate() 中无效
【发布时间】:2017-12-05 06:08:32
【问题描述】:

我正在尝试为用户显示倒数计时器。 Function(myfunc) 通过单击按钮即可完美运行。但我想在活动创建后立即运行它。在 Oncreate 方法中。但是 myfunc 在 OnCreate 方法中不起作用。

这是MainActivity的代码

public class MainActivity extends AppCompatActivity {
private enum TimerState {
    STOPPED,
    RUNNING
}

private static final long TIMER_LENGHT = 60; // Sixty seconds
private long mTimeToGo;
private CountDownTimer mCountDownTimer;
private TimerState mState;

@BindView(R.id.main_timer)
TextView mTimerText;

@BindView(R.id.main_timer_button)
Button mTimerButton;

PrefUtils mPreferences;
long startTime;
Calendar rightNow;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    mState=TimerState.STOPPED;
    mPreferences = new PrefUtils(this);
    startTime = mPreferences.getStartedTime();
    rightNow = Calendar.getInstance();


            myfunc();



}

@Override
protected void onResume()
{
    super.onResume();
    initTimer();
    removeAlarm();
}
@Override
protected void onPause() {
    super.onPause();
    if (mState == TimerState.RUNNING) {
        mCountDownTimer.cancel();
        setAlarm();
    }
}
private long getNow()
{

    return rightNow.getTimeInMillis() / 1000;
}

private void initTimer()
{

    if (startTime >= 0)
    {
        mTimeToGo = (TIMER_LENGHT - (getNow() - startTime));
        if (mTimeToGo <= 0)
        { // TIMER EXPIRED
            mTimeToGo = TIMER_LENGHT;
            mState = TimerState.STOPPED;
            onTimerFinish();
        }
        else
        {
            startTimer();
            mState = TimerState.RUNNING;
        }
    }
    else
    {
        mTimeToGo = TIMER_LENGHT;
        mState = TimerState.STOPPED;
    }
    updateTimeUi();
}

private void onTimerFinish()
{

    Toast.makeText(getApplicationContext(),R.string.timer_finished,Toast.LENGTH_LONG).show();
    mTimerText.setText(R.string.timer_finished);
    mPreferences.setStartedTime(0);
    mTimeToGo=TIMER_LENGHT ;
    updateTimeUi();
}

private void updateTimeUi()
{
    mTimerText.setText(String.valueOf(mTimeToGo));
}

private void startTimer()
{
    mCountDownTimer = new CountDownTimer(mTimeToGo*1000 , 1000) {
        public void onTick(long millisUntilFinished)
        {
            mTimeToGo -= 1;
            updateTimeUi();
        }
        public void onFinish()
        {
            mState = TimerState.STOPPED;
            onTimerFinish();
            updateTimeUi();
        }
    }.start();
}


public void myfunc()
{
    if  (mState == TimerState.STOPPED) {
        mPreferences.setStartedTime(getNow());
        startTimer();
        mState = TimerState.RUNNING;
    }
}

public void setAlarm() {
    long wakeUpTime = (mPreferences.getStartedTime() + TIMER_LENGHT) * 1000;
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, TimerExpiredReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        am.setAlarmClock(new AlarmManager.AlarmClockInfo(wakeUpTime, sender), sender);
    } else {
        am.set(AlarmManager.RTC_WAKEUP, wakeUpTime, sender);
    }
}

public void removeAlarm() {
    Intent intent = new Intent(this, TimerExpiredReceiver.class);
    PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    am.cancel(sender);
}

}

这里有一个实用程序代码

class PrefUtils {
private static final String STARTED_TIME_ID = "com.whiterabbit.time";
private SharedPreferences mPreferences;

PrefUtils(Context c)
{
    mPreferences = PreferenceManager.getDefaultSharedPreferences(c);
}

long getStartedTime()
{
    return mPreferences.getLong(STARTED_TIME_ID, 0);
}

void setStartedTime(long started) {
    SharedPreferences.Editor editor = mPreferences.edit();
    editor.putLong(STARTED_TIME_ID, started);
    editor.apply();
}

}

广播接收器也在这里

 @Override
public void onReceive(Context context, Intent intent)
{
    Intent i = new Intent(context, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pIntent = PendingIntent.getActivity(context, 0, i, 0);

    NotificationCompat.Builder b = new NotificationCompat.Builder(context);
    Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    b.setSound(notification)
            .setContentTitle(context.getString(R.string.timer_finished))
            .setAutoCancel(true)
            .setContentText(context.getString(R.string.timer_finished))
            .setSmallIcon(android.R.drawable.ic_notification_clear_all)
            .setContentIntent(pIntent);

    Notification n = b.build();
    NotificationManager mNotificationManager =
            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(0, n);
}

【问题讨论】:

  • 把你的代码放在 onResume
  • 您正在 onResume 中启动计时器,该计时器在 onCreate 方法之后调用。这就是它不起作用的原因。
  • 说明你想做什么,我相信有更简单的方法
  • 我正在使用修复倒数计时器。即使用户杀死活动,当用户在杀死活动后再次打开应用程序时,倒数计时器应该在杀死活动后运行,它应该显示经过的时间。现在剩下的时间

标签: android countdowntimer


【解决方案1】:

在调用 myfunc 之前调用 initTimer 一次。因为 onResume 将在 onCreate 之后调用或在 oncreate 中延迟几秒钟

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mState=TimerState.STOPPED;
mPreferences = new PrefUtils(this);
startTime = mPreferences.getStartedTime();
rightNow = Calendar.getInstance();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
myfunc();     
}
}, 100);//Delay 100ms

}

【讨论】:

  • 应用切换后,当活动对用户可见时,计时器将重新启动。它不应该从哪里开始。在按钮单击时,它不会重新启动,直到时间结束。即使应用程序被杀死。
  • 那么这种情况你会延迟几毫秒然后调用 myfunc(); oncreate
  • 还是上面评论中提到的问题。
  • 到达 onCreate 方法时的 mState 状态是什么?
  • 默认是 mState=STOPPED。
【解决方案2】:

在延迟一段时间后尝试以编程方式单击按钮

button.postDelayed(new Runnable() {  //delay button 
     public void run() {  
         button.performClick();
         button.setPressed(true); 
        
     }
 }, 800);

【讨论】:

  • 最好能解释一下为什么你认为这会奏效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多