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,等等,只是告诉你,因为它可能会让你的代码更容易读。