如何使用线程概念在countdowntimer中运行后台应用程序?

时间:2012-02-07 12:48:16

标签: java android

我想在倒计时器中创建一个后台应用程序,即如果我正在启动 计时器从该应用程序出来,然后转到另一个应用程序 回到同样的倒计时器应用程序。我想要那个计时器 一直跑到我停下来。我知道它涉及的方法,但我不确定 关于其中使用的线程概念。

//MyActivity.class

     import android.app.Activity;
     import android.content.Intent;
     import android.os.Bundle;
     import android.util.Log;
     import android.view.View;
     import android.widget.Button;
     import android.widget.TextView;

     public class MyappActivity extends Activity 
     {
    private static final String Tag = "Background_Timer";
    private Button start;
    private Button stop;
    private TextView tv;

    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        start = (Button) findViewById(R.id.button);
        stop = (Button) findViewById(R.id.button1);

        tv = (TextView) findViewById(R.id.text1);

        this.runOnUiThread(new Runnable() 
        {
            public void run() 
            {
                tv.setText(MyAppService.seconds + " Seconds Left");
            }
        });

    }

    public void onClick(View src) 
    {
        switch (src.getId()) 
        {
        case R.id.button:
            Log.e(Tag, "onClick: starting service");
            startService(new Intent(this, MyAppService.class));
            break;

        case R.id.button1:
            Log.e(Tag, "onClick: stopping service");
            stopService(new Intent(this, MyAppService.class));
            break;
        }
    }
        }

        //MyService.class

        import android.app.Service;
        import android.content.Intent;
        import android.os.CountDownTimer;
        import android.os.IBinder;
        import android.util.Log;
        import android.widget.TextView;

        public class MyAppService extends Service 
        {

    private static final String TAG = "My Service";
    private static boolean state;
    private static TextView TextTimer;
    public static String seconds;

    MyThread mt = new MyThread();

    @Override
    public void onCreate() 
    {

        CountDownTimer Myapp = new CountDownTimer(50000, 1000) 
        {
            public void onTick(long millisUntilFinished) 
            {
                TextTimer.setText("Seconds left: " + (millisUntilFinished)
                        / 1000);
            }

            public void onFinish() 
            {
                TextTimer.setText("Finished!");
            }
        };  
    }

    public void onStart(Intent intent, int startid) 
    {
        Log.d(TAG, "on-Start");
        mt.start();
    }

    public void onDestroy() 
    {
        Log.d(TAG, "on-Stop");
        mt.stop();
    }

    public static class MyThread extends Thread 
    {

        public void run() 
        {
            try 
            {
                while (state = true) 
                {
                    MyThread.sleep(500);
                }
            } 
            catch (InterruptedException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            };
        }
    }

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

3 个答案:

答案 0 :(得分:1)

在您的活动中有一个静态处理程序,它接收您的勾选和完成消息

在Service中有一个启动CountDown的线程,这样你的CountDown将在你的线程中工作而不是在主线程中。

答案 1 :(得分:0)

您可以将TimerTask类用于此目的。它与线程相同,但允许您基于时间间隔执行任务。您还可以在其run方法中执行可重复任务。

请查看简单示例here

答案 2 :(得分:0)

首先:你不应该在应用程序UI线程中运行CountDownTimer,因为这可能会导致ANR(应用程序没有响应)问题。

您可以将SheduledThreadPoolExecutor与自定义Runnable一起使用,也可以使用Bound Service。要回调实际活动(如果它正在运行,您可以使用不同的方法,例如通过Observer Pattern订阅或使用LocalBroadcastManager发送Intents,然后在其自己的线程中更新UI。

你也可以像Lucifer指出的那样使用TimerTask,但是在更新视图时确保Runnable调用runOnUiThread。