在循环中服务崩溃 - Android Studio
我基本搭售打开一项服务,每10秒钟,将显示吐司说“10秒过去” 这就是我想要做的, 经过许多研究发现,要循环服务我 需要使用while(true) - sleep ... method ... 但服务或我的应用程序崩溃每次我开始服务 在循环中服务崩溃 - Android Studio
什么是我的问题(或每次定时器溢出时间是精确的)?
我的猜测是,也许我传递给敬酒contaxt是错误的? 也许还有另一种方式来显示在循环(在一个serivice中)每10秒钟吐司?
这里是我的服务代码>
package com.greenroad.candidate.mywallpaperchanger;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
/**
* Created by pitsponet on 31/08/2015.
*/
public class myService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(getApplicationContext(), "service created",
Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//try to run loop for showing up a toast
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
while(true)
{
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//REST OF CODE HERE//
Toast.makeText(getApplicationContext(), "service started",
Toast.LENGTH_LONG).show();
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(), "service stoped",
Toast.LENGTH_LONG).show();
}
}
的原因坠毁,由布拉德解释说,是因为您试图从非UI执行UI操作Thread
。
为了达到你想要做的,在服务中使用下面的代码是什么。首先,删除你Thread
在onStartCommand()
public class MyService extends Service {
private Handler mHandler;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mHandler.postDelayed(ToastTask, 10000); // Starts the loop here
super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// Stop the loop
mHandler.removeCallbacks(ToastTask);
super.onDestroy();
}
private Runnable ToastTask = new Runnable() {
@Override
public void run() {
Toast.makeText(MyService.this, "10 Seconds have passed", Toast.LENGTH_SHORT).show();
// Schedule this Runnable to run again after 10 sec
mHandler.postDelayed(this, 10000);
}
}
}
我不相信,因为他正在创造一个新的线程无限的,这是正确的,同时循环在onStartCommand()方法。 – Bradford2000
@ Bradford2000对不起。我现在看到了。我的解决方案虽然会工作。我认为它和你的一样,尽管我的看起来更加完整。 – DavidH
试图将它添加到我的onStartCommand,但没有奏效,因为它输出配发错误的,你在哪里加呢?以及你如何调用这个循环? –
的原因,该服务崩溃是因为你想在主线程之外运行的UI任务(干杯)。既然你正在创建while循环无限辅助线程,你需要发表您的吐司调用主尺蠖如下:
final Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Text to display", Toast.LENGTH_LONG).show();
}
});
话虽这么说,我非常使用Thread.sleep()方法阻止任何将在设备上运行的代码,因为这可能会导致一些严重的问题。您应该能够使用Timer来完成相同的操作(并且还可以摆脱无限循环)。
要使用Timer,你应该能够做到像下面这样:
// Schedules a TimerTask to execute every 10 seconds after a 10 second delay.
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// Your Toast code here.
}
}, 10000, 10000);
这里有一个完整的例子:
public class MyService extends Service {
private Handler mainHandler;
private Timer timer;
public void onStartCommand(final Intent intent, final int flags, final int startId) {
mainHandler = new Handler(getApplicationContext().getMainLooper());
timer = new Timer();
timer.schedule(new MyTimerTask(), 10000, 10000);
}
public void onDestroy() {
timer.cancel();
}
private class MyTimerTask extends TimerTask {
@Override
public void run() {
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Text to display", Toast.LENGTH_LONG).show();
}
});
}
}
}
太棒了,这确实显示了敬酒,但我如何循环呢?你有我需要投入的计时器的代码示例吗?试图寻找它徒劳的 –
编辑包括计时器的例子。此外,@DavidH在上面发布的答案在功能上是等价的,只是使用Handler而不是Timer来进行循环。 – Bradford2000
如果它崩溃了,你应该能够得到一个堆栈跟踪。尝试发布,因为它将提供更多的细节,以了解发生了什么。 – Acapulco
哎阿卡普尔科,unfortuntly我不能堆栈跟踪它becouse我建立这个作为一个APK文件,并将其上传到我的设备,目前的Android Studio不会看到我的设备,而且在它的模拟器不工作,所以我无法以其他方式检查它。 –
我更新了我的答案。我希望你现在很清楚。 – DavidH