2012-09-19 40 views
8

Possible Duplicate:
Android Toast started from Service only displays once錯誤從服務的Android調用敬酒

我使用android.app.Service定義服務的Android。

我從活動中調用此服務(myService)。

爲MyService是:

public class myService extends Service{ 

public IBinder onBind(Intent intent){ 
    return null; 
} 

public void onCreate(){ 
    super.onCreate(); 
    TimerTask task = new TimerTask(){ 
     public void run(){ 
      Log.i("test","service running"); 
      checkDate();    
     }   
    }; 
    timer = new Timer(); 
    timer.schedule(task, 0, 20000); 
} 

public void checkDate(){ 
    Toast toast = Toast.makeText(this, "SIMPLE MESSAGE!", Toast.LENGTH_LONG); 
    toast.show(); 
} 

} 

的方法了checkdate()駐留在類爲myService。

產生的錯誤是:

09-19 15:41:35.267: E/AndroidRuntime(2026): FATAL EXCEPTION: Timer-0 
09-19 15:41:35.267: E/AndroidRuntime(2026): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
09-19 15:41:35.267: E/AndroidRuntime(2026): at android.os.Handler.<init>(Handler.java:121) 
09-19 15:41:35.267: E/AndroidRuntime(2026): at android.widget.Toast$TN.<init>(Toast.java:310) 
09-19 15:41:35.267: E/AndroidRuntime(2026): at android.widget.Toast.<init>(Toast.java:84) 
09-19 15:41:35.267: E/AndroidRuntime(2026): at android.widget.Toast.makeText(Toast.java:226) 
+0

你能後的代碼,你用它來啓動這個?這是一個實際的Android服務還是隻是一個後臺線程?問題是你無法從後臺線程與UI進行交互。如果您有活動上下文的引用,則可以使用該上下文調用runOnUIThread。 – Bobbake4

回答

23

TimerTask運行在一個單獨的線程。 Toast.makeText()必須從已建立Handler/Looper的線程執行。基本上這意味着你需要在擁有標準Android消息/事件分派器的線程上執行Toast。要做到這一點會在你的checkDate()方法

最簡單的方法:

runOnUiThread(new Runnable() { 
    public void run() { 
     Toast toast = Toast.makeText(this, "SIMPLE MESSAGE!", Toast.LENGTH_LONG); 
     toast.show(); 
    } 
}); 

編輯:我是個白癡,那是不對的。你不能從服務上下文調用runOnUiThread()

你需要爲此使用Handler。在您的服務:

private Handler handler; 
在服務的 onCreate()

handler = new Handler(); 

checkDate()方法:

handler.post(new Runnable() { 
    public void run() { 
     Toast toast = Toast.makeText(myService.this, "SIMPLE MESSAGE!", Toast.LENGTH_LONG); 
     toast.show(); 
    } 
}); 
+0

我試過這個,但是返回這個錯誤:方法runOnUiThread(new Runnable(){})未定義類型myService – GVillani82

+0

對不起,我是個白癡。我相應地編輯了我的帖子。你需要爲此使用Handler。 –

+0

好的。 「makeText」只是另一個問題:類型Toast中的方法makeText(Context,CharSequence,int)不適用於參數(new Runnable(){},String,int) – GVillani82

4

你從一個工作線程調用它。您需要在主線程中調用Toast.makeText()(以及處理UI的大多數其他函數)。例如,您可以使用處理程序。

你需要從UI線程調用Toast.makeText(...):

activity.runOnUiThread(new Runnable() { 
    public void run() { 
    Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show(); 
    } 
}); 
+0

+1哎呀,你打敗了我。 –

+0

如果我嘗試這個,我得到這個錯誤:無法對類型爲Activity的非靜態方法runOnUiThread(Runnable)進行靜態引用 – GVillani82

+2

是的,除非你有一個活動上下文,否則這是行不通的。 –