Android每X秒运行一次线程

时间:2022-07-07 01:07:24

I want to create a thread in an Android service that runs every X seconds

我想在Android服务中创建一个每X秒运行一次的线程

I am currently using , but the postdelayed method seems to really lag out my app.

我目前正在使用,但是postdelayed方法似乎真的让我的应用程序落后了。

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

    super.onStartCommand(intent, flags, startId);

    startRepeatingTask();

    return startId;

}

private final static int INTERVAL = 20000; //20 milliseconds
Handler m_handler = new Handler();

Runnable m_handlerTask = new Runnable()
{
     @Override 
     public void run() {
         // this is bad
          m_handler.postDelayed(m_handlerTask, INTERVAL);



     }
};

void startRepeatingTask()
{
    m_handlerTask.run(); 
}

void stopRepeatingTask()
{
   m_handler.removeCallbacks(m_handlerTask);
   stopSelf();
}

I want to do a new thread like this:

我想做一个像这样的新思路:

   public void threadRun()
{
    Thread triggerService = new Thread(new Runnable(){
        public void run(){
            Looper.prepare();
            try{
                    //do stuff here?

            }catch(Exception ex){
                    System.out.println("Exception in triggerService Thread -- "+ex);
            }//end catch


        }//end run
  }, "aThread");
  triggerService.start();


  //perhaps do stuff here with a timer?
  timer1=new Timer();

  timer1.scheduleAtFixedRate(new methodTODOSTUFF(), 0, INTERVAL);
  }

I'm not sure the best way to do a background thread to run at a certain interval, insight appreciated!

我不确定在一定的时间间隔内运行后台线程的最佳方式,敬请谅解!

4 个解决方案

#1


52  

There are number of alternative ways to do this. Personally, I prefer to use ScheduledExecutorService:

有很多其他的方法可以做到这一点。我个人更喜欢使用ScheduledExecutorService:

ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);

// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
  public void run() {
    doSomethingUseful();
  }
}, 0, 2, TimeUnit.MINUTES);

#2


4  

Here is how I run a repeating thread, as you'll see it loops every 1 second. I see no lag with this method.

这是我如何运行一个循环线程,你会看到它每1秒循环一次。我看这种方法没有什么滞后性。

final Thread t = new Thread(new RepeatingThread());
t.start();

And the class:

和类:

import android.os.Handler;

public class RepeatingThread implements Runnable {

    private final Handler mHandler = new Handler();

    public RepeatingThread() {

    }

    @Override
    public void run() { 
        mHandler.postDelayed(this, 1000);       
    }
}

#3


2  

MyService.java

MyService.java

public class MyService extends Service {

    public static final int notify = 5000;  //interval between two services(Here Service run every 5 seconds)
    int count = 0;  //number of times service is display
    private Handler mHandler = new Handler();   //run on another Thread to avoid crash
    private Timer mTimer = null;    //timer handling

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        if (mTimer != null) // Cancel if already existed
            mTimer.cancel();
        else
            mTimer = new Timer();   //recreate new
        mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify);   //Schedule task
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mTimer.cancel();    //For Cancel Timer
        Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show();
    }

    //class TimeDisplay for handling task
    class TimeDisplay extends TimerTask {
        @Override
        public void run() {
            // run on another thread
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // display toast
                    Toast.makeText(MyService.this, "Service is running", Toast.LENGTH_SHORT).show();
                }
            });

        }

    }
}

MainActivity.java

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(this, MyService.class)); //start service which is MyService.java
    }
}

Add following code in AndroidManifest.xml

在AndroidManifest.xml中添加以下代码

AndroidManifest.xml

AndroidManifest.xml

<service android:name=".MyService" android:enabled="true" android:exported="true"></service>

#4


0  

Starting a runnable every few seconds is gonna have some lag no matter what way you slice it, no? I don't see why a Handler shouldn't work just fine.

每隔几秒就开始一次跑步会有一些延迟不管你怎么切,不是吗?我不明白为什么一个处理程序不能正常工作。

You might be experiencing some troubles though because you have

你可能会遇到一些麻烦,因为你有

void startRepeatingTask()
{
    m_handlerTask.run(); 
}

Instead, you should use the Handler and do something like:

相反,您应该使用处理程序,并执行以下操作:

void startRepeatingTask()
{
    m_handler.post(m_handlerTask); 
}

(As an aside, the convention in Java is to use camel case, not snake case. So it should be mHandler, not m_handler, etc. Just telling you because it might make your code easier to read for some.)

(顺便说一句,Java中的约定是使用camel case,而不是snake case。所以它应该是mHandler,而不是m_handler,等等,只是告诉你,因为它可能会让你的代码更容易读。

#1


52  

There are number of alternative ways to do this. Personally, I prefer to use ScheduledExecutorService:

有很多其他的方法可以做到这一点。我个人更喜欢使用ScheduledExecutorService:

ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);

// This schedule a runnable task every 2 minutes
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
  public void run() {
    doSomethingUseful();
  }
}, 0, 2, TimeUnit.MINUTES);

#2


4  

Here is how I run a repeating thread, as you'll see it loops every 1 second. I see no lag with this method.

这是我如何运行一个循环线程,你会看到它每1秒循环一次。我看这种方法没有什么滞后性。

final Thread t = new Thread(new RepeatingThread());
t.start();

And the class:

和类:

import android.os.Handler;

public class RepeatingThread implements Runnable {

    private final Handler mHandler = new Handler();

    public RepeatingThread() {

    }

    @Override
    public void run() { 
        mHandler.postDelayed(this, 1000);       
    }
}

#3


2  

MyService.java

MyService.java

public class MyService extends Service {

    public static final int notify = 5000;  //interval between two services(Here Service run every 5 seconds)
    int count = 0;  //number of times service is display
    private Handler mHandler = new Handler();   //run on another Thread to avoid crash
    private Timer mTimer = null;    //timer handling

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        if (mTimer != null) // Cancel if already existed
            mTimer.cancel();
        else
            mTimer = new Timer();   //recreate new
        mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify);   //Schedule task
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mTimer.cancel();    //For Cancel Timer
        Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show();
    }

    //class TimeDisplay for handling task
    class TimeDisplay extends TimerTask {
        @Override
        public void run() {
            // run on another thread
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // display toast
                    Toast.makeText(MyService.this, "Service is running", Toast.LENGTH_SHORT).show();
                }
            });

        }

    }
}

MainActivity.java

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(this, MyService.class)); //start service which is MyService.java
    }
}

Add following code in AndroidManifest.xml

在AndroidManifest.xml中添加以下代码

AndroidManifest.xml

AndroidManifest.xml

<service android:name=".MyService" android:enabled="true" android:exported="true"></service>

#4


0  

Starting a runnable every few seconds is gonna have some lag no matter what way you slice it, no? I don't see why a Handler shouldn't work just fine.

每隔几秒就开始一次跑步会有一些延迟不管你怎么切,不是吗?我不明白为什么一个处理程序不能正常工作。

You might be experiencing some troubles though because you have

你可能会遇到一些麻烦,因为你有

void startRepeatingTask()
{
    m_handlerTask.run(); 
}

Instead, you should use the Handler and do something like:

相反,您应该使用处理程序,并执行以下操作:

void startRepeatingTask()
{
    m_handler.post(m_handlerTask); 
}

(As an aside, the convention in Java is to use camel case, not snake case. So it should be mHandler, not m_handler, etc. Just telling you because it might make your code easier to read for some.)

(顺便说一句,Java中的约定是使用camel case,而不是snake case。所以它应该是mHandler,而不是m_handler,等等,只是告诉你,因为它可能会让你的代码更容易读。