Dịch vụ nền trước bị Android khai tử


84

Cập nhật : Tôi chưa tìm thấy giải pháp thực sự cho vấn đề. Những gì tôi đã nghĩ ra là một phương pháp tự động kết nối lại với thiết bị bluetooth trước đó bất cứ lúc nào kết nối bị mất. Nó không phải là lý tưởng, nhưng nó có vẻ hoạt động khá tốt. Tôi rất muốn nghe thêm bất kỳ đề xuất nào về điều này.

Tôi đang gặp vấn đề tương tự như trong câu hỏi này: Dịch vụ bị tắt khi giữ khóa chế độ thức và sau khi gọi startForeground bao gồm thiết bị (Asus Transformer), khoảng thời gian trước khi dịch vụ bị dừng (30-45 phút), việc sử dụng khóa đánh thức, việc sử dụng startForeground () và thực tế là vấn đề không xảy ra nếu ứng dụng đang mở khi màn hình tắt.

Ứng dụng của tôi duy trì kết nối bluetooth với một thiết bị khác và gửi dữ liệu giữa hai thiết bị, vì vậy, ứng dụng phải luôn hoạt động để lắng nghe dữ liệu. Người dùng có thể bắt đầu và dừng dịch vụ theo ý muốn, và trên thực tế đây là cách duy nhất tôi đã triển khai để bắt đầu hoặc dừng dịch vụ. Khi dịch vụ khởi động lại, kết nối bluetooth với thiết bị khác sẽ bị mất.

Theo câu trả lời trong câu hỏi được liên kết, startForeground () "làm giảm khả năng dịch vụ bị giết, nhưng không ngăn chặn nó". Tôi hiểu đó là trường hợp, tuy nhiên tôi đã thấy nhiều ví dụ về các ứng dụng khác không gặp sự cố này (ví dụ: Tasker).

Tính hữu ích của ứng dụng của tôi sẽ bị giảm đáng kể mà không có khả năng dịch vụ chạy cho đến khi người dùng dừng. Có cách nào để tránh điều này???

Tôi thấy điều này trong logcat của mình bất cứ khi nào dịch vụ bị dừng:

ActivityManager: No longer want com.howettl.textab (pid 32321): hidden #16
WindowManager: WIN DEATH: Window{40e2d968 com.howettl.textab/com.howettl.textab.TexTab paused=false
ActivityManager: Scheduling restart of crashed service com.howettl.textab/.TexTabService in 5000ms

CHỈNH SỬA: Tôi cũng nên lưu ý, điều này dường như không xảy ra trên thiết bị khác mà tôi đang kết nối: HTC Legend chạy Cyanogen

EDIT: Đây là đầu ra của adb shell dumpsys activity services:

* ServiceRecord{40f632e8 com.howettl.textab/.TexTabService}

intent={cmp=com.howettl.textab/.TexTabService}

packageName=com.howettl.textab

processName=com.howettl.textab

baseDir=/data/app/com.howettl.textab-1.apk

resDir=/data/app/com.howettl.textab-1.apk

dataDir=/data/data/com.howettl.textab

app=ProcessRecord{40bb0098 2995:com.howettl.textab/10104}

isForeground=true foregroundId=2 foregroundNoti=Notification(contentView=com.howettl.textab/0x1090087 vibrate=null,sound=null,defaults=0x0,flags=0x6a)

createTime=-25m42s123ms lastActivity=-25m42s27ms

 executingStart=-25m42s27ms restartTime=-25m42s124ms

startRequested=true stopIfKilled=false callStart=true lastStartId=1

Bindings:

* IntentBindRecord{40a02618}:

  intent={cmp=com.howettl.textab/.TexTabService}

  binder=android.os.BinderProxy@40a9ff70

  requested=true received=true hasBound=true doRebind=false

  * Client AppBindRecord{40a3b780 ProcessRecord{40bb0098 2995:com.howettl.textab/10104}}

    Per-process Connections:

      ConnectionRecord{40a76920 com.howettl.textab/.TexTabService:@40b998b8}

All Connections:

  ConnectionRecord{40a76920 com.howettl.textab/.TexTabService:@40b998b8}

Và đầu ra của adb shell dumpsys activity:

* TaskRecord{40f5c050 #23 A com.howettl.textab}

numActivities=1 rootWasReset=false

affinity=com.howettl.textab

intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.howettl.textab/.TexTab}

realActivity=com.howettl.textab/.TexTab

lastActiveTime=4877757 (inactive for 702s)

* Hist #1: ActivityRecord{40a776c8 com.howettl.textab/.TexTab}

    packageName=com.howettl.textab processName=com.howettl.textab

    launchedFromUid=2000 app=ProcessRecord{40bb0098 2995:com.howettl.textab/10104}

    Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.howettl.textab/.TexTab }

    frontOfTask=true task=TaskRecord{40f5c050 #23 A com.howettl.textab}

    taskAffinity=com.howettl.textab

    realActivity=com.howettl.textab/.TexTab

    base=/data/app/com.howettl.textab-1.apk/data/app/com.howettl.textab-1.apk data=/data/data/com.howettl.textab

    labelRes=0x7f060000 icon=0x7f020000 theme=0x0

    stateNotNeeded=false componentSpecified=true isHomeActivity=false

    configuration={ scale=1.0 imsi=0/0 loc=en_CA touch=3 keys=2/1/1 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=6}

    launchFailed=false haveState=true icicle=Bundle[mParcelledData.dataSize=1644]

    state=STOPPED stopped=true delayedResume=false finishing=false

    keysPaused=false inHistory=true visible=false sleeping=true idle=true

    fullscreen=true noDisplay=false immersive=false launchMode=2

    frozenBeforeDestroy=false thumbnailNeeded=false

    connections=[ConnectionRecord{40a76920 com.howettl.textab/.TexTabService:@40b998b8}]

...

Proc #15: adj=prcp /F 40e75070 959:android.process.acore/10006 (provider)

          com.android.providers.contacts/.ContactsProvider2<=Proc{40bb0098 2995:com.howettl.textab/10104}

Proc #16: adj=bak+2/F 40bb0098 2995:com.howettl.textab/10104 (foreground-service)

Những điều này dường như cho thấy dịch vụ đang chạy ở nền trước.


Hãy xem câu trả lời này - việc sức mạnh cho bạn stackoverflow.com/a/21157035/624109
Muzikant

Câu trả lời:


218

Được rồi. Tôi đã trải qua địa ngục và trở lại vấn đề này. Đây là cách tiến hành. Có lỗi. Bài đăng này mô tả cách phân tích lỗi trong quá trình triển khai và giải quyết các vấn đề.

Tóm lại, đây là cách mọi thứ hoạt động. Các dịch vụ đang chạy sẽ được quét và chấm dứt định kỳ sau mỗi 30 phút hoặc lâu hơn. Các dịch vụ muốn tồn tại lâu hơn thời gian này phải gọi Service.startForeground, nơi đặt thông báo trên thanh thông báo, để người dùng biết rằng dịch vụ của bạn đang hoạt động vĩnh viễn và có khả năng ngốn pin. Chỉ có 3 quy trình dịch vụ có thể tự đề cử làm dịch vụ nền tại bất kỳ thời điểm nào. Nếu có nhiều hơn ba dịch vụ nền trước, Android sẽ chỉ định dịch vụ cũ nhất làm ứng cử viên để thu thập và chấm dứt.

Thật không may, có những lỗi trong Android liên quan đến việc ưu tiên các dịch vụ nền trước, được kích hoạt bởi nhiều tổ hợp cờ ràng buộc dịch vụ khác nhau. Mặc dù bạn đã chỉ định chính xác dịch vụ của mình làm dịch vụ nền, Android vẫn có thể chấm dứt dịch vụ của bạn, nếu bất kỳ kết nối nào với các dịch vụ trong quy trình của bạn đã từng được thực hiện với một số kết hợp cờ ràng buộc nhất định. Thông tin chi tiết được đưa ra bên dưới.

Lưu ý rằng rất ít dịch vụ cần phải là dịch vụ nền trước. Nói chung, bạn chỉ cần là một dịch vụ nền nếu bạn có một kết nối internet hoạt động liên tục hoặc lâu dài thuộc một loại nào đó mà người dùng có thể bật và tắt hoặc hủy. Ví dụ về các dịch vụ cần trạng thái nền: máy chủ UPNP, tải xuống lâu dài các tệp rất lớn, đồng bộ hóa hệ thống tệp bằng wi-fi và phát nhạc.

Nếu bạn chỉ thỉnh thoảng thăm dò ý kiến, hoặc chờ đợi trên bộ thu phát sóng của hệ thống hoặc các sự kiện hệ thống, tốt hơn hết bạn nên đánh thức dịch vụ của mình trên bộ hẹn giờ hoặc phản hồi với bộ thu phát sóng và sau đó để dịch vụ của bạn chết sau khi hoàn tất. Đó là hành vi như được thiết kế cho các dịch vụ. Nếu bạn chỉ đơn giản là phải sống sót, thì hãy đọc tiếp.

Sau khi chọn các hộp trên các yêu cầu đã biết (ví dụ: gọi Service.startForeground), nơi tiếp theo cần xem xét là các cờ bạn sử dụng trong các lệnh gọi Context.bindService. Các cờ được sử dụng để ràng buộc ảnh hưởng đến mức độ ưu tiên của quy trình dịch vụ mục tiêu theo nhiều cách không mong muốn. Đặc biệt nhất, việc sử dụng một số cờ ràng buộc nhất định có thể khiến Android hạ cấp sai dịch vụ nền của bạn xuống dịch vụ thông thường. Mã được sử dụng để chỉ định mức độ ưu tiên của quy trình đã bị xáo trộn khá nhiều. Đáng chú ý, có những bản sửa đổi trong API 14+ có thể gây ra lỗi khi sử dụng cờ ràng buộc cũ hơn; và có một số lỗi nhất định trong 4.2.1.

Bạn của bạn trong tất cả những điều này là tiện ích sysdump, có thể được sử dụng để tìm ra mức độ ưu tiên mà Người quản lý hoạt động đã chỉ định cho quy trình dịch vụ của bạn và phát hiện các trường hợp nó đã chỉ định mức độ ưu tiên không chính xác. Thiết lập và chạy dịch vụ của bạn, sau đó đưa ra lệnh sau từ dấu nhắc lệnh trên máy tính chủ của bạn:

adb shell kết xuất các quy trình hoạt động> tmp.txt

Sử dụng notepad (không phải wordpad / write) để kiểm tra nội dung.

Trước tiên, hãy xác minh rằng bạn đã quản lý thành công để chạy dịch vụ của mình ở trạng thái nền trước. Phần đầu tiên của tệp kết xuất chứa mô tả về các thuộc tính ActivityManager cho mỗi quy trình. Tìm một dòng như sau tương ứng với ứng dụng của bạn trong phần đầu tiên của tệp kết xuất:

APP UID 10068 ProcessRecord {41937d40 2205: tunein.service / u0a10068}

Xác minh rằng foregroundServices = true trong phần sau. Đừng lo lắng về các cài đặt ẩn và trống; chúng mô tả trạng thái của các Hoạt động trong quy trình và dường như không liên quan đặc biệt đến các quy trình có dịch vụ trong đó. Nếu foregroundService không đúng, bạn cần gọi Service.startForeground để biến nó thành true.

Điều tiếp theo bạn cần xem là phần gần cuối tệp có tiêu đề "Process LRU list (sắp xếp theo oom_adj):". Các mục trong danh sách này cho phép bạn xác định xem Android có thực sự phân loại ứng dụng của bạn là dịch vụ nền hay không. Nếu quy trình của bạn ở cuối danh sách này, thì đó là một ứng cử viên chính cho việc tiêu diệt tóm tắt. Nếu quy trình của bạn ở gần đầu danh sách, thì nó hầu như không thể phá hủy được.

Hãy xem một dòng trong bảng này:

  Proc #31: adj=prcp /FS trm= 0 2205:tunein.service/u0a10068 (fg-service)

Đây là một ví dụ về dịch vụ nền trước được thực hiện đúng mọi thứ. Trường quan trọng ở đây là trường "adj =". Điều đó cho biết mức độ ưu tiên mà quy trình của bạn đã được ActivityManagerService chỉ định sau khi mọi thứ đã được nói là xong. Bạn muốn nó là "adj = prcp" (dịch vụ nền trước có thể nhìn thấy); hoặc "adj = vis" (quy trình hiển thị với một hoạt động) hoặc "fore" (quy trình có hoạt động tiền cảnh). Nếu đó là "adj = svc" (quy trình dịch vụ) hoặc "adj = svcb" (dịch vụ kế thừa?) Hoặc "adj = bak" (quy trình nền trống), thì quy trình của bạn có khả năng bị chấm dứt và sẽ bị chấm dứt thường xuyên hơn 30 phút một lần ngay cả khi không có bất kỳ áp lực nào để lấy lại bộ nhớ. Các cờ còn lại trên dòng hầu hết là thông tin gỡ lỗi chẩn đoán cho các kỹ sư của Google. Quyết định chấm dứt được thực hiện dựa trên các trường điều chỉnh. Một cách ngắn gọn, / FS chỉ ra một dịch vụ nền trước; / FA chỉ ra một quá trình tiền cảnh với một hoạt động. / B cho biết một dịch vụ nền. Nhãn ở cuối cho biết quy tắc chung mà quy trình được chỉ định mức độ ưu tiên. Thường thì nó phải khớp với trường adj =; nhưng giá trị adj = có thể được điều chỉnh lên hoặc xuống trong một số trường hợp do các cờ ràng buộc trên các ràng buộc đang hoạt động với các dịch vụ hoặc hoạt động khác.

Nếu bạn đã vấp phải một lỗi với cờ ràng buộc, đường kết xuất sẽ trông như thế này:

  Proc #31: adj=bak /FS trm= 0 2205:tunein.service/u0a10068 (fg-service)

Lưu ý rằng giá trị của trường adj được đặt không chính xác thành "adj = bak" (quy trình nền trống), dịch gần nghĩa là "vui lòng chấm dứt hoạt động của tôi ngay bây giờ để tôi có thể chấm dứt sự tồn tại vô nghĩa này" cho mục đích nhặt rác của quy trình. Cũng lưu ý cờ (fg-service) ở cuối dòng cho biết rằng "các quy tắc dịch vụ nền được sử dụng để xác định cài đặt" adj ". Mặc dù thực tế là các quy tắc fg-service đã được sử dụng, quy trình này được chỉ định một cài đặt điều chỉnh "bak", và nó sẽ không tồn tại được lâu. Nói một cách dễ hiểu, đây là một lỗi.

Vì vậy, mục tiêu là đảm bảo rằng quy trình của bạn luôn nhận được "adj = prcp" (hoặc tốt hơn). Và phương pháp để đạt được mục tiêu đó là điều chỉnh các cờ ràng buộc cho đến khi bạn quản lý để tránh các lỗi trong phân công ưu tiên.

Đây là những lỗi tôi biết. (1) Nếu BẤT KỲ dịch vụ hoặc hoạt động nào đã từng ràng buộc với dịch vụ bằng Context.BIND_ABOVE_CLIENT, bạn có nguy cơ cài đặt adj = sẽ bị hạ cấp xuống "bak" ngay cả khi ràng buộc đó không còn hoạt động nữa. Điều này đặc biệt đúng nếu bạn cũng có ràng buộc giữa các dịch vụ. Một lỗi rõ ràng trong các nguồn 4.2.1. (2) Chắc chắn không bao giờ sử dụng BIND_ABOVE_CLIENT để ràng buộc dịch vụ với dịch vụ. Cũng không sử dụng nó cho các kết nối hoạt động với dịch vụ. Cờ được sử dụng để triển khai hành vi BIND_ABOVE_CLIENT dường như được đặt trên cơ sở từng quy trình, thay vì cơ sở từng kết nối, do đó, nó gây ra lỗi với các ràng buộc giữa dịch vụ với dịch vụ ngay cả khi không có hoạt động nào đang hoạt động ràng buộc với bộ cờ. Dường như cũng có vấn đề với việc thiết lập mức độ ưu tiên khi có nhiều dịch vụ trong quá trình này, với các ràng buộc giữa dịch vụ với dịch vụ. Sử dụng Context.BIND_WAIVE_PRIORITY (API 14) trên các ràng buộc dịch vụ với dịch vụ dường như hữu ích. Context.BIND_IMPORTANT dường như là một ý tưởng tốt ít nhiều khi liên kết từ Hoạt động với một dịch vụ. Làm như vậy sẽ đẩy mức độ ưu tiên quy trình của bạn cao hơn một bậc khi Hoạt động ở nền trước, mà không gây tác hại rõ ràng nào khi Hoạt động bị tạm dừng hoặc kết thúc.

Nhưng nhìn chung, chiến lược là điều chỉnh các cờ bindService của bạn cho đến khi sysdump chỉ ra rằng quy trình của bạn đã nhận được ưu tiên chính xác.

Đối với mục đích của tôi, sử dụng Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT đối với ràng buộc Hoạt động với dịch vụ và Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY để ràng buộc dịch vụ với dịch vụ dường như làm đúng. Số dặm của bạn có thể khác.

Ứng dụng của tôi khá phức tạp: hai dịch vụ nền, mỗi dịch vụ có thể độc lập giữ trạng thái dịch vụ nền trước, cộng với một phần ba cũng có thể có trạng thái dịch vụ nền; hai trong số các dịch vụ ràng buộc với nhau theo điều kiện; cái thứ ba liên kết với cái đầu tiên, luôn luôn. Ngoài ra, các Activites chạy trong một quy trình riêng biệt (làm cho hoạt ảnh mượt mà hơn). Việc chạy các Hoạt động và Dịch vụ trong cùng một quy trình dường như không tạo ra bất kỳ sự khác biệt nào.

Có thể tìm thấy việc triển khai các quy tắc cho quy trình quét rác (và mã nguồn được sử dụng để tạo nội dung của tệp sysdump) trong tệp android lõi

frameworks\base\services\java\com\android\server\am\ActivityManagerService.java.

Cơ hội tốt.

Tái bút: Đây là cách giải thích các chuỗi sysdump cho Android 5.0. Tôi chưa làm việc với họ, vì vậy hãy làm cho họ những gì bạn sẽ làm. Tôi tin rằng bạn muốn 4 là 'A' hoặc 'S', và 5 là "IF" hoặc "IB" và 1 là càng thấp càng tốt (có thể là dưới 3, vì chỉ có 3 ba quy trình dịch vụ nền trước được duy trì hoạt động trong cấu hình mặc định).

Example:
   Proc # : prcp  F/S/IF trm: 0 31719: neirotech.cerebrum.attention:blePrcs/u0a77 (fg-service)

Format:
   Proc # {1}: {2}  {3}/{4}/{5} trm: {6} {7}: {8}/{9} ({10}

1: Order in list: lower is less likely to get trimmed.

2: Not sure.

3:
    B: Process.THREAD_GROUP_BG_NONINTERACTIVE
    F: Process.THREAD_GROUP_DEFAULT

4:
    A: Foreground Activity
    S: Foreground Service
    ' ': Other.

5:
    -1: procState = "N ";
        ActivityManager.PROCESS_STATE_PERSISTENT: procState = "P ";
    ActivityManager.PROCESS_STATE_PERSISTENT_UI:procState = "PU";
    ActivityManager.PROCESS_STATE_TOP: procState = "T ";
    ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: procState = "IF";
    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: procState = "IB";
    ActivityManager.PROCESS_STATE_BACKUP:procState = "BU";
    ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: procState = "HW";
    ActivityManager.PROCESS_STATE_SERVICE: procState = "S ";
    ActivityManager.PROCESS_STATE_RECEIVER: procState = "R ";
    ActivityManager.PROCESS_STATE_HOME: procState = "HO";
    ActivityManager.PROCESS_STATE_LAST_ACTIVITY: procState = "LA";
    ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: procState = "CA";
    ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: procState = "Ca";
    ActivityManager.PROCESS_STATE_CACHED_EMPTY: procState = "CE";

{6}: trimMemoryLevel

{8} Process ID.
{9} process name
{10} appUid 

4
@Robin Davies, tôi có một câu hỏi nhỏ. Tôi có thực sự cần gọi bindService()nếu tôi cần Dịch vụ chạy liên tục không? Chỉ gọi startForeground()trong dịch vụ là không đủ ? Để giao tiếp với máy chủ, tôi sử dụng EventBus.
ar-g

Bạn gọi Context.bindService từ Activity để dịch vụ chạy ngay từ đầu. Phương thức Service.startService được gọi bằng mã trong dịch vụ để chuyển một dịch vụ đã được khởi động sang trạng thái "nền trước". Tôi giả sử rằng thư viện EventBus đang gọi Context.bindService thay mặt bạn tại một số thời điểm để bắt đầu dịch vụ. Nếu có một cách khác để bắt đầu một dịch vụ, tôi không quen với nó.
Robin Davies

3
Bài rất hay! Đã ủng hộ. Một phần tôi muốn thêm vào nhận xét này, mà tôi tin là có liên quan. Nếu bạn muốn một dịch vụ chạy liên tục, như Robin đã đề cập, bạn cần phải khởi động nó bằng cách nào đó. Có thể gọi startService (Dịch vụ ý định) trực tiếp bên trong hoạt động của bạn thay vì bindService (), và sau đó khi dịch vụ của bạn khởi động, bạn có thể gọi phương thức startForeground (). Tôi gọi điều này trong onStartCommand () của lớp dịch vụ. Theo như tôi biết, điều này sẽ làm cho dịch vụ của bạn không bị ràng buộc, nhưng giữ cho nó chạy các vấn đề tài nguyên đang chờ xử lý. Hy vọng rằng điều này sẽ giúp ai đó.
Dave

Công việc tuyệt vời !! Tôi muốn thêm một bản cập nhật cho điều này. Đầu tiên, định dạng đầu ra của adb đã thay đổi một chút (tháng 1 năm 2016). Tôi đã thử nghiệm quy trình này trên hai thiết bị LG Volt 4.4.2 và Nexus 5x 6.0.1 cả hai thiết bị vẫn bị lỗi. Tôi chỉ có thể tái tạo sự cố bằng cách sử dụng Context.BIND_ABOVE_CLIENT: Proc # 4: cch F / S / SF trm: 0 12354: com.test / u0a78 (fg-service) Sử dụng cờ gặp sự cố sẽ gây ra lỗi tức thì hầu hết thời gian trên phiên bản cũ hơn thiết bị sau khi thoát khỏi hoạt động. Tất cả các cờ khác dường như hoạt động tốt trên cả hai phiên bản Android.
user3259330

1
@ Xin chào Dave, tôi sử dụng chính xác phương pháp đó, cũng như trả lại START_STICKY, nhưng dịch vụ của tôi luôn ngừng hoạt động sau một giờ hoặc lâu hơn khi thiết bị không hoạt động. Bạn có bất cứ ý tưởng về những gì có thể xảy ra
Ruchir Baronia

7

Nếu nó nói "không còn muốn ..." thì quá trình đó không có dịch vụ đang hoạt động trong nó mà hiện đang ở trạng thái startForeground (). Kiểm tra để đảm bảo rằng cuộc gọi của bạn đến đó thực sự thành công - rằng bạn đang thấy thông báo được đăng, không có thông báo nào trong nhật ký tại thời điểm đó phàn nàn về bất kỳ điều gì, v.v. Ngoài ra, hãy sử dụng "dịch vụ hoạt động adb shell bãi" để xem trạng thái của dịch vụ của bạn và đảm bảo rằng nó thực sự được đánh dấu là nền trước. Ngoài ra, nếu nó là tiền cảnh chính xác thì trong đầu ra của "adb shell bãi activity", bạn sẽ thấy trong phần hiển thị điều chỉnh OOM của các quy trình mà quy trình của bạn hiện đang ở cấp tiền cảnh do dịch vụ đó.


Cảm ơn đã giúp đỡ! Tôi đã chỉnh sửa câu hỏi của mình với đầu ra của các lệnh bạn đã đề cập. Chúng dường như chỉ ra rằng dịch vụ đang chạy ở phía trước.
howettl

Có đoạn mã nào tôi có thể đăng có thể giúp chẩn đoán không?
howettl

1
Nó chắc chắn không nên bị giết khi đang ở phía trước, và tôi biết chắc rằng những thứ như Âm nhạc trong nền tảng tiêu chuẩn thì không. Cân nhắc gửi lỗi bằng mã để tái tạo sự cố. Một điều cần xem xét là nếu bạn đang di chuyển ra vào tiền cảnh ở bất kỳ điểm nào có thể cho phép nó bị giết.
hackbod

1
Có thể cập nhật thông báo đang diễn ra bằng cách gọi thông báo () thay vì gọi startForeground () một lần nữa có thể đưa nó ra khỏi trạng thái nền trước không? Tôi cũng đã bật FLAG_ALERT_ONLY_ONCE trên thông báo nếu điều đó quan trọng.
howettl

2
Chắc chắn không cập nhật nó thông qua trình quản lý thông báo. Bạn đang đăng điều này thông qua dịch vụ và nên tiếp tục cập nhật nó thông qua dịch vụ.
hackbod
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.