2012-09-13 37 views
3

我檢查this question,但它似乎並沒有回答我的問題,這涉及更少。我從我的主進程中的菜單項調用IntentService。它目前只是一個框架,它在onHandleIntent()中放置一個Toast,最終應該在處理結束時簡單出現,以表示它已完成。然而,它始終保持在屏幕上(即使應用程序已停止)。我用模擬器和我的Galaxy S2測試了相同的結果。請有人指出我正確的方向嗎?Android:從IntentService吐司仍然在屏幕上永遠

這是服務代碼:

package com.enborne.spine; 

import android.app.IntentService; 
import android.content.Intent; 
import android.util.Log; 
import android.widget.Toast; 

public class SaveFile extends IntentService { 
    private final String TAG = "SaveFile"; 

    public SaveFile() { 
     super("SaveFile"); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d(TAG, "Service Started.. "); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(TAG, "Service Destroyed.. "); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     // TODO Auto-generated method stub 
     Log.d(TAG, "HandleIntent"); 
     // File saved 
     Toast.makeText(this, "File has been saved", Toast.LENGTH_SHORT).show(); 
    } 
} 

(本的onCreate和的onDestroy覆蓋只是有暫時在Eclipse中的日誌記錄,所以我可以看到發生了什麼。)

我調用它從一個菜單活動因此(與上下文搞亂只是因爲服務沒有啓動 - 一些白癡忘了把它列入清單!):

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    Intent i; 
    switch (item.getItemId()) { 
    case R.id.chart: 
     i = new Intent(getBaseContext(), Chart.class); 
     i.putExtra(KEY_CENTRE_LAT, mCentreLat); // centre coordinate 
     i.putExtra(KEY_CENTRE_LONG, mCentreLong); // centre coordinate 
     i.putExtra(KEY_RADIUS, mRadius); // effective radius 
     startActivity(i); 
     break; 

    case R.id.save: 
     Log.d("SaveFile", "Starting service..."); 
     //  i = new Intent(getBaseContext(), SaveFile.class); 
     i = new Intent(this, SaveFile.class); 
     startService(i); 
     break; 
    } 
    return true; 
} 

編輯:我發現this article,這可能解釋了這個問題。引用一句話:

但是,您只能在主GUI線程中使用Toast,否則會遇到Toast消息在一段時間後不會消失的問題(因爲主GUI上下文不知道在單獨的線程環境中使用Toast消息的任何事情)。

+0

這聽起來像你的''onHandleIntent''被多次調用,你可以從LogCat驗證這是否是這種情況? – harism

+0

僅當菜單項被點擊時才被調用一次。另外,我沒有看到應用程序退出後如何調用它。從日誌中也可以看出它是否被多次調用(參見上面的日誌代碼)。 –

+0

它發生在我意外的一次,我不小心把吐司放在渲染線程。它讓我的吐司在我退出該計劃後大約10分鐘後出現 - 這是因爲吐司排隊。你想確保你只顯示一次烤麪包而不是10-100次,例如與我一樣。 – harism

回答

8

鏈接到我編輯的文章導致我this blog修復了我的問題。我沒有在別處看到你不能直接從服務中發出祝酒詞。所以我onHandleIntent現在看起來是這樣的:

private Handler handler; 

@Override 
protected void onHandleIntent(Intent intent) 
{ 
    Log.d(TAG, "onHandleIntent"); 

    /* Stripped out some code here that I added later to keep it similar to 
    * my example above 
    */ 

    handler.post(new Runnable() 
    { 
//  @Override 
     public void run() 
     { 
      Toast.makeText(getApplicationContext(), "File has been saved", 
       Toast.LENGTH_SHORT).show(); 
     } 
    }); // Display toast and exit 
} 

(如果任何人都可以解釋爲什麼我不得不註釋掉@覆蓋上運行(),以避免錯誤,我將不勝感激還有其他幾個地方。我的申請,我必須這樣做。)

編輯:我剛纔發現this post這幾乎是同一件事。我不知道我以前是怎麼錯過的。

+2

在Java 5中,不能在接口上使用@Override。在Java 6中,你可以(也應該)。 http://stackoverflow.com/questions/212614/should-a-method-that-implements-an-interface-method-be-annotated-with-override –

2

onHandleIntent在工作線程中執行。

我會嘗試從UI線程執行Toast.show()。

+0

是的,謝謝 - 我到了那裏! :) –