用Service+Broadcast解决倒计时过程中Activity被销毁的问题详解手机开发

主要思想是这样的:将倒计时CountDownTimer放在Service里面进行,每过一秒就一条发广播,在主Activity里注册广播,收到广播后更新UI。

一、写一个类CodeTimerService继承自Service,重写onStartCommand(…)方法。

@Override   
public int onStartCommand(Intent intent, int flags, int startId) {   

    // 第一个参数是总时间, 第二个参数是间隔    
    mCodeTimer = new CountDownTimer(60000, 1000) {   
        @Override   
        public void onTick(long millisUntilFinished) {   
            // 广播剩余时间    
            broadcastUpdate(IN_RUNNING, millisUntilFinished / 1000 + "");   
        }   

        @Override   
        public void onFinish() {   
            // 广播倒计时结束   
            broadcastUpdate(END_RUNNING);   
            // 停止服务   
            stopSelf();   
        }   
    };   
    // 开始倒计时   
    mCodeTimer.start();   
    return super.onStartCommand(intent, flags, startId);   
}   

// 发送广播   
private void broadcastUpdate(final String action) {   
    final Intent intent = new Intent(action);   
    sendBroadcast(intent);   
}   

// 发送带有数据的广播   
private void broadcastUpdate(final String action, String time) {   
    final Intent intent = new Intent(action);   
    intent.putExtra("time", time);   
    sendBroadcast(intent);   
}

先了解一下CountDownTimer怎么用:
创建CountDownTimer实例时传入两个参数,第一个参数是总时间, 第二个参数是间隔;需要重写onTick(long millisUntilFinished)和onFinish()两个回调方法,前者表示倒计时进行中,后者表示倒计时结束,在方法中写处理事件;最后调用start()方法开始倒计时。

二、在主Activity中注册广播,接收广播,更新UI

// 注册广播   
private static IntentFilter updateIntentFilter() {   
        final IntentFilter intentFilter = new IntentFilter();   
        intentFilter.addAction(RegisterCodeTimerService.IN_RUNNING);   
        intentFilter.addAction(RegisterCodeTimerService.END_RUNNING);   return intentFilter;   
    }   
 // 广播接收者   
 private final BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {   
        @Override   
        public void onReceive(Context context, Intent intent) {   
            final String action = intent.getAction();   
            switch (action) {   
            case RegisterCodeTimerService.IN_RUNNING:   
            if (btnCountdown.isEnabled())   
                        btnCountdown.setEnabled(false);   
                        // 正在倒计时   
                    btnCountdown.setText("倒计时中(" + intent.getStringExtra("time") + ")");   
                    Log.e(TAG, "倒计时中(" + intent.getStringExtra("time") + ")");   
                    break;   
                    case RegisterCodeTimerService.END_RUNNING:   // 完成倒计时   
                    btnCountdown.setEnabled(true);   
                    btnCountdown.setText(R.string.countdown);   
                break;   
            }   
        }   
    };   
    @Override   protected void onResume() {   
        super.onResume();   
        // 注册广播           
        registerReceiver(mUpdateReceiver, updateIntentFilter());   
    }   
   
    @Override   protected void onPause() {   
        super.onPause();   
        // 移除注册           
        unregisterReceiver(mUpdateReceiver);   
    }

最后补上例子的源代码:跨Activity的倒计时源代码

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/3083.html

(0)
上一篇 2021年7月16日
下一篇 2021年7月16日

相关推荐

发表回复

登录后才能评论