Android 内部服务天文钟

Android 内部服务天文钟,android,chronometer,Android,Chronometer,我有一个下面的计时器实现。我想在服务中使用它,然后将其输出发送到我的片段。问题是服务没有findViewById(),因为它显然根本没有视图。有没有办法让计时器在服务内工作?如果没有,我可以用什么代替 代码: 一个选择就是使用 postDelayed(Runnable r, long milliseconds) 在不使用服务的情况下,为任何更新周期触发可运行更新方法。然后在更新方法中更新UI 另一个选择是使用AsyncTask而不是服务,如果您打算在后台做一些事情的话。AsyncTask可以通

我有一个下面的计时器实现。我想在
服务中使用它
,然后将其输出发送到我的片段。问题是
服务
没有
findViewById()
,因为它显然根本没有
视图
。有没有办法让计时器在
服务
内工作?如果没有,我可以用什么代替

代码:


一个选择就是使用

postDelayed(Runnable r, long milliseconds)
在不使用服务的情况下,为任何更新周期触发可运行更新方法。然后在更新方法中更新UI

另一个选择是使用AsyncTask而不是服务,如果您打算在后台做一些事情的话。AsyncTask可以通过其
onProgressUpdate()
方法访问UI,您可以在那里完成自己的工作

如果必须使用服务,则必须从服务广播到UI活动,并让UI活动执行视图更新:

这是您的主要活动:

private StatusReceiver mReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ...

    mReceiver = new StatusReceiver();

    ...
}


@Override
protected void onStart() {
    // Register the broadcast receiver
    IntentFilter filter = new IntentFilter();
    filter.addAction(getString(R.string.ACTION_UPDATE_CHRONO));
    filter.addCategory(Intent.CATEGORY_DEFAULT);
    registerReceiver(mReceiver, filter);

    ...
}

@Override
protected void onStop() {
    ...
    unregisterReceiver(mReceiver);
    ...
}

public class StatusReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if( action.equals(getString(R.string.ACTION_UPDATE_CHRONO)) ) {
             // Do your UI stuff here
        } 
    }
}
在服务类中:

private void broadcast(String status, Exception error) {
    Intent broadcastIntent = new Intent((Intent) getText(R.string.ACTION_UPDATE_CHRONO));
    broadcastIntent.putExtra("STATUS", status);
    broadcastIntent.putExtra("ERROR", error);
    sendBroadcast(broadcastIntent);
}

当您希望向主要活动传达某些“状态”时,请调用此方法,例如
“更新时间”
“将chrono设置为“+x+”milli”

确保代码更面向GUI(无耗时的操作,高频率)将其移动到服务中是没有意义的。我只需要测量服务启动后的时间并将其发送到片段(如果片段存在)。好的,然后使用intents传递一个包含时间戳的长的额外参数。但是请注意,当作业完成时,服务可能会停止(或自行停止),甚至可能被系统终止。如果使用
ScheduledThreadPoolExecutor.scheduleAtFixedRate()
而不是
postDelayed
,是否可以?。我希望避免在循环内重新调度。我没有使用ScheduledThreadPoolExecutor的实践经验,但文档似乎适合使用它。虽然如果您的目标是测量服务运行的净时间,您应该从绑定服务的那一刻开始计数,直到它被解除为止,但要注意在每次服务被破坏时暂停时间计数,并在重新创建时恢复计时。
private void broadcast(String status, Exception error) {
    Intent broadcastIntent = new Intent((Intent) getText(R.string.ACTION_UPDATE_CHRONO));
    broadcastIntent.putExtra("STATUS", status);
    broadcastIntent.putExtra("ERROR", error);
    sendBroadcast(broadcastIntent);
}