android - 在后台使用服务实现倒数计时器

标签 android service countdowntimer

我想在我的应用程序中做什么: 1. 当用户打开应用程序时,他将能够看到一个已经在运行的倒计时计时器。所以在那种情况下,我想在始终每秒更新的 TextView 中显示倒计时数字。 2. 用户将能够停止它。 3. 用户可以离开应用程序,但返回应用程序界面时倒计时仍应继续并显示更新时间。

所以基于以上几点,我明白我需要实现在后台工作的服务。我读过this链接,但我的问题在于实现。我对如何实现这种方式一无所知。话虽如此,我也想不出一种方法来在用户返回应用程序后在 UI 中显示时间。我也看到了this link同样,但我不确定是否仅实现 CountDownTimer 就可以使其成为正在运行的服务。 那么我应该如何着手实现呢?感谢任何指向特定教程/代码的链接。谢谢。

更新:到目前为止,我已经能够做到以下几点: 主 Activity .java

public class MainActivity extends Activity {

Button btnStart,btnStop;
Intent serviceIntent;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnStart = (Button) findViewById(R.id.btnStart);
    btnStop = (Button) findViewById(R.id.btnStop);
    tv = (TextView) findViewById(R.id.timeView);

    //final MyCounter timer = new MyCounter(100000,1000);
    //tv.setText("100"); 
    //timer.start();
    serviceIntent = new Intent(MainActivity.this,MyService.class);

    btnStart.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            startService(serviceIntent);
        }
    });

    btnStop.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            stopService(serviceIntent);
        }
    });
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

我的服务.java:

public class MyService extends Service {

MyCounter timer;
@Override
public void onCreate() {
    // TODO Auto-generated method stub
    timer = new MyCounter(100000,1000);
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    timer.start();
    return super.onStartCommand(intent, flags, startId);
}
private class MyCounter extends CountDownTimer{

    public MyCounter(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
    }

    @Override
    public void onFinish() {
        Toast.makeText(getApplicationContext(), "death", Toast.LENGTH_LONG).show();
        stopSelf();
    }

    @Override
    public void onTick(long millisUntilFinished) {

        Toast.makeText(getApplicationContext(), (millisUntilFinished/1000)+"", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    timer.cancel();
    //stopSelf();
    super.onDestroy();

}

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

    }

问题是: 1. 除了这个 Toast,我不知道如何在 MainActivity UI 上显示倒计时。 2. 当我按下停止按钮时它不会停止计数。

最佳答案

使用 bindService(Intent service, ServiceConnection conn, int flag) 绑定(bind)您的倒计时服务,然后在您的服务中返回包含计数的 Binder ,在您的 Activity 中,实例化的 ServiceConnection 对象可以处理 Binder 。 AIDL也可以做到这一点,建议先看看如何绑定(bind)服务,希望能帮到你。

演示

public class BindService extends Service{
private int count;
private boolean quit;
private MyBinder binder = new MyBinder();
// My Binder
public class MyBinder extends Binder
{
    public int getCount()
    {
        // get the counting status:count
        return count;
    }
}

@Override
public IBinder onBind(Intent intent)
{
    System.out.println("Service is Binded");
    // return the binder instance
    return binder;
}

@Override
public void onCreate()
{
    super.onCreate();
    System.out.println("Service is Created");
    // counting work
    new Thread()
    {
        @Override
        public void run()
        {
            while (!quit)
            {
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                }
                count++;
            }
        }
    }.start();      
}
// invoke when the service unbind
@Override
public boolean onUnbind(Intent intent)
{
    System.out.println("Service is Unbinded");
    return true;
}

@Override
public void onDestroy()
{
    super.onDestroy();
    this.quit = true;
    System.out.println("Service is Destroyed");
}

@Override
public void onRebind(Intent intent) 
{
    super.onRebind(intent);
    this.quit = true;
    System.out.println("Service is ReBinded");
}   

然后是 Activity

public class MainActivity extends Activity{
Button bind , unbind , getServiceStatus;
BindService.MyBinder binder;
// define a ServiceConnection object
private ServiceConnection conn = new ServiceConnection()
{
    // then the Activity connected with the Service, this will be called
    @Override
    public void onServiceConnected(ComponentName name
        , IBinder service)
    {
        System.out.println("--Service Connected--");
        // achieve MyBinder instance
        binder = (BindService.MyBinder) service;
    }
    // then the connection break off
    @Override
    public void onServiceDisconnected(ComponentName name)
    {
        System.out.println("--Service Disconnected--");         
    }
};
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    bind = (Button) findViewById(R.id.bind);
    unbind = (Button) findViewById(R.id.unbind);
    getServiceStatus = (Button) findViewById(R.id.getServiceStatus);

    final Intent intent = new Intent();

    intent.setAction("org.crazyit.service.BIND_SERVICE");       
    bind.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View source)
        {
            //bind Serivce
            bindService(intent , conn , Service.BIND_AUTO_CREATE);  
        }
    });
    unbind.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View source)
        {
            //unbind Serivce
            unbindService(conn);
        }
    }); 
    getServiceStatus.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View source)
        {
            // Toast to show the conut value
            Toast.makeText(MainActivity.this
                , "Serivce's count value is:" + binder.getCount()
                , 4000)
                .show();
        }
    });
}}

关于android - 在后台使用服务实现倒数计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16382186/

相关文章:

android - 有效地绘制位于 fragment 内部的 imageView 以响应触摸事件

java - Enum 中的空静态方法

android - 升级到 ADT 20 后,键盘在 Intel x86 Android 模拟器上停止工作

android - 无法解析 : com. google.firebase :firebase-firestore:11. 4.2

java - 我应该如何在 Spring 中实现缓存对象/系统?

java - Guava的AbstractExecutionThreadService可以复用吗?

android - 倒计时服务

javascript - 如何从倒计时器获取剩余时间?

Android CountDownTimer 减慢应用程序页面转换

java - 在 Android 上滚动 RecyclerView 时如何修复计时器?