2012-03-29 109 views
7

我有一個IntentService,我想用正在進行的通知使它變得粘滯。問題是通知出現,然後立即消失。該服務繼續運行。我應該如何在IntentService中使用startForeground?IntentService的StartForeground

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent, flags, startId); 
    Notification notification = new Notification(R.drawable.marker, "Notification service is running", 
      System.currentTimeMillis()); 
    Intent notificationIntent = new Intent(this, DashboardActivity.class); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| 
     Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 
    notification.setLatestEventInfo(this, "App", 
      "Notification service is running", pendingIntent); 
    notification.flags|=Notification.FLAG_NO_CLEAR; 
    startForeground(1337, notification); 
    return START_STICKY; 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    String id = intent.getStringExtra(ID); 
    WebSocketConnectConfig config = new WebSocketConnectConfig(); 
    try { 
     config.setUrl(new URI("ws://" + App.NET_ADDRESS 
       + "/App/socket?id="+id)); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 
    ws = SimpleSocketFactory.create(config, this); 
    ws.open(); 
} 

感謝

+2

包括你的代碼太 – waqaslam 2012-03-29 18:00:26

回答

9

這不應該是一個IntentService。正如所寫的,你的IntentService將活一毫秒左右。一旦onHandleIntent()返回,服務將被銷燬。這應該是一個普通的Service,您可以在其中分配自己的線程並管理線程和服務的生命週期。

您的Notification立即消失的原因是因爲服務立即失效。

+1

謝謝,我將它轉換的服務,現在它的工作。 – Matroska 2012-03-29 18:50:08

+2

Downvoted,因爲:這可能是一個不正確的答案。摘自IntentService docs:「所有請求都在單個工作線程上處理 - *它們可能需要的時間*(並且不會阻塞應用程序的主循環),但一次只能處理一個請求。」沒有說什麼毫秒左右。 https://developer.android.com/reference/android/app/IntentService。html – GregoryK 2016-12-02 07:48:01

+1

正如所寫的,這個'IntentService'將會持續一毫秒左右的時間,原因很簡單,因爲'onHandleIntent()'中的代碼只需要幾毫秒的時間就可以運行。 – CommonsWare 2017-07-17 11:04:39

1

至於documentationIntentService狀態:

...根據需要啓動該服務,處理在使用 工作線程按順序將每意圖,當它運行的工作停止本身。

所以,我想問題是,onHandleIntent()完成後,你的服務失效。因此,服務會自行停止,通知就會消失。因此,IntentService的概念可能不是您的任務的最佳案例。


由於問題的標題是「StartForeground爲IntentService」,我想澄清一些事情:

這真的很簡單,讓您IntentService在前臺運行(見下面的代碼),但是可以肯定你需要考慮幾件事情:

  • 如果只需要幾秒鐘就不要在前臺運行服務 - 這可能會影響用戶。假設你定期執行短任務 - 這將導致通知出現和消失 - uhhhh *

  • 您可能需要使您的服務能夠保持設備喚醒狀態(但這是另一個故事,在stackoverflow上覆蓋得非常好)*

  • 如果您將多個Intent排隊到您的IntentService,則下面的代碼將最終顯示/隱藏通知。 (所以對你的情況可能會有更好的解決方案 - 正如@CommonsWare建議擴展Service並自己做所有事情一樣,然而要提一下--Javadoc中沒有什麼IntentService表示它只能運行幾秒鐘 - 只要它必須做一些事情。)


public class ForegroundService extends IntentService { 

    private static final String TAG = "FrgrndSrv"; 

    public ForegroundService() { 
     super(TAG); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     Notification.Builder builder = new Notification.Builder(getBaseContext()) 
       .setSmallIcon(R.drawable.ic_foreground_service) 
       .setTicker("Your Ticker") // use something from something from R.string 
       .setContentTitle("Your content title") // use something from something from 
       .setContentText("Your content text") // use something from something from 
       .setProgress(0, 0, true); // display indeterminate progress 

     startForeground(1, builder.build()); 
     try { 
      doIntesiveWork(); 
     } finally { 
      stopForeground(true); 
     } 
    } 

    protected void doIntesiveWork() { 
     // Below should be your logic that takes lots of time 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

計算機編程的一般規則是:絕對不要對代表您獲取的資源做出假設。你沒有創建'IntentService'使用的後臺線程;因此,你不應該假設你可以安全地使用它多久。我們用'AsyncTask'解決了這個問題,Google改變了'execute()'的規則,將所有任務限制爲一個線程。如果您想要保持一段時間超過一段時間,請創建您自己的線程。用於推薦令人尷尬的編程習慣的下調。 – CommonsWare 2016-12-02 12:06:54

+1

@CommonsWare我明白你的觀點並理解它。這就說得通了。實際上,我對這個陳述有些不同意:「按照書面的說法,你的IntentService會活幾毫秒。」 API並沒有試圖做出假設:「IntentService是服務的基類,可以按需處理異步請求(表示爲Intents),客戶通過startService(Intent)調用發送請求;服務根據需要啓動,依次使用工作線程處理每個Intent,並在工作完成時自行停止。「 – GregoryK 2016-12-02 12:47:36