[英]Why does my app crash when my service makes an alertdialog?
嗨,我正在嘗試讓用戶投入一段時間后在后台運行的服務。 在這段時間之后,會出現alartDialog,並且用戶選擇的鈴聲會響起,直到他們取消它為止。 不幸的是,我收到一個導致我的應用崩潰的錯誤。 如果您需要更多信息,請詢問:)
我的服務等級
import java.util.Timer;
import java.util.TimerTask;
import org.holoeverywhere.app.AlertDialog;
import org.holoeverywhere.preference.PreferenceManager;
import org.holoeverywhere.preference.SharedPreferences;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;
public class CountDownService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
int hour = 990;
int min = 990;
int sec = 990;
Context c;
AlertDialog alertDialog;
SharedPreferences getPrefs;
Vibrator v;
Ringtone r;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("timeLeft");
String[] strArray = input.split(",");
c = this.getApplicationContext();
getPrefs = PreferenceManager.getDefaultSharedPreferences(c);
v = (Vibrator) c.getSystemService(Context.VIBRATOR_SERVICE);
build();
for (String t : strArray) {
if (hour == 990) {
hour = Integer.parseInt(t);
} else {
if (min == 990) {
min = Integer.parseInt(t);
}else{
if (sec == 990) {
sec = Integer.parseInt(t);
}
}
}
}
Timer timer = new Timer();
TimerTask tt = new TimerTask() {
@Override
public void run() {
sec--;
updateTime();
}
};
timer.schedule(tt, 0, 1000);
return START_STICKY;
}
private void build() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(c);
// set title
alertDialogBuilder.setTitle("Time's up!!!");
// set dialog message
alertDialogBuilder.setMessage("Press OK to stop alarm")
.setCancelable(true)
.setNeutralButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (r != null) {
if (r.isPlaying()) {
r.stop();
}
}
alertDialog.cancel();
alertDialog.cancel();
}
});
alertDialog = alertDialogBuilder.create();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
private void updateTime() {
if (hour <= 0 && min <= 0 && sec <= 0) {
done();
}
if (sec < 0) {
min --;
sec = 59;
}
if (min < 0) {
hour --;
min = 59;
}
}
private void done() {
Uri uri;
boolean notmuted = getPrefs.getBoolean("Muted", true);
boolean viberate = getPrefs.getBoolean("Viberate", true);
String strRingtonePreference = getPrefs.getString("app_ringtone",
null);
Log.v("Alarm", "a " + strRingtonePreference);
if (viberate) {
v.vibrate(1000);
}
if (notmuted) {
if (strRingtonePreference != null) {
uri = Uri.parse(strRingtonePreference);
Log.v("Alarm", "was parsed");
} else {
Log.v("Alarm", "was not parsed");
uri = null;
}
playSound(this.getApplicationContext(), uri);
}
}
private void playSound(Context context, Uri alert) {
r = RingtoneManager.getRingtone(context, alert);
if (r != null) {
r.play();
Log.v("Alarm", "was not null");
}
alertDialog.show();
}
}
我的日志
02-10 19:13:07.875: E/AndroidRuntime(23231): FATAL EXCEPTION: Timer-0
02-10 19:13:07.875: E/AndroidRuntime(23231): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
02-10 19:13:07.875: E/AndroidRuntime(23231): at android.os.Handler.<init>(Handler.java:121)
02-10 19:13:07.875: E/AndroidRuntime(23231): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:371)
02-10 19:13:07.875: E/AndroidRuntime(23231): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
02-10 19:13:07.875: E/AndroidRuntime(23231): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
02-10 19:13:07.875: E/AndroidRuntime(23231): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
02-10 19:13:07.875: E/AndroidRuntime(23231): at android.app.Dialog.show(Dialog.java:278)
02-10 19:13:07.875: E/AndroidRuntime(23231): at com.chair49.holotimer.CountDownService.playSound(CountDownService.java:169)
02-10 19:13:07.875: E/AndroidRuntime(23231): at com.chair49.holotimer.CountDownService.done(CountDownService.java:147)
02-10 19:13:07.875: E/AndroidRuntime(23231): at com.chair49.holotimer.CountDownService.updateTime(CountDownService.java:113)
02-10 19:13:07.875: E/AndroidRuntime(23231): at com.chair49.holotimer.CountDownService.access$0(CountDownService.java:111)
02-10 19:13:07.875: E/AndroidRuntime(23231): at com.chair49.holotimer.CountDownService$1.run(CountDownService.java:67)
02-10 19:13:07.875: E/AndroidRuntime(23231): at java.util.Timer$TimerImpl.run(Timer.java:284)
您不能從后台線程調用UI內容。 您可以使用runOnUiThread() 。
我終於明白了。 我要做的是開始一個新活動並創建警報對話框,然后從那里發出聲音,然后結束活動。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.