我正在测试一个使用Service,Thread和Messenger的简单Android应用。我注意到当我快速启动并停止服务时,我有时会得到NullPointerException和FORCE CLOSE。我调试它,发现我的Messenger实例有时为null,因此我的处理程序不会被调用。我究竟做错了什么?在重新启动服务之前是否需要等待?
确定它刚刚发生,没有快速停止/启动服务。所以我不确定如何重现这个问题。它可能是随机发生的。
我可以捕获异常并摆脱FORCE CLOSE,但这并不能解决我的处理程序在Messenger实例为空时不被调用的问题。我查看了Managing the Lifecycle of a Service上的服务文档部分,我没有看到任何提及在重新启动服务之前必须等待。
这就是我启动服务的方式:
Intent backgroundService = new Intent(PlayAudio.this, com.marie.mp3player.BackgroundService.class);
backgroundService.putExtra(BackgroundService.EXTRA_MESSENGER, new Messenger(handler));
backgroundService.putExtra(BackgroundService.EXTRA_SONG, song);
startService(backgroundService);
这就是我停止服务的方式:
Intent backgroundService = new Intent(MP3Player.this, BackgroundService.class);
stopService(backgroundService);
这是一个logcat,底部附近有两个NullPointerExceptions:
D/AndroidRuntime(17736):
D/AndroidRuntime(17736): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
D/AndroidRuntime(17736): CheckJNI is OFF
D/dalvikvm(17736): creating instr width table
D/AndroidRuntime(17736): Calling main entry com.android.commands.pm.Pm
I/ActivityManager( 96): Start proc com.android.defcontainer for service com.android.defcontainer/.DefaultContainerService: pid=17744 uid=10011 gids={1015, 2001}
D/dalvikvm(17744): GC_EXPLICIT freed 46K, 50% free 2720K/5379K, external 1625K/2137K, paused 34ms
W/ActivityManager( 96): No content provider found for:
D/PackageParser( 96): Scanning package: /data/app/vmdl-1782488429.tmp
W/ActivityManager( 96): No content provider found for:
I/PackageManager( 96): Removing non-system package:com.marie.mp3player
I/ActivityManager( 96): Force stopping package com.marie.mp3player uid=10091
D/PackageManager( 96): Scanning package com.marie.mp3player
I/PackageManager( 96): Package com.marie.mp3player codePath changed from /data/app/com.marie.mp3player-2.apk to /data/app/com.marie.mp3player-1.apk; Retaining data and using new
I/PackageManager( 96): Unpacking native libraries for /data/app/com.marie.mp3player-1.apk
D/installd( 70): DexInv: --- BEGIN '/data/app/com.marie.mp3player-1.apk' ---
D/dalvikvm(17752): creating instr width table
D/dalvikvm(17752): DexOpt: load 5ms, verify+opt 18ms
D/installd( 70): DexInv: --- END '/data/app/com.marie.mp3player-1.apk' (success) ---
D/PackageManager( 96): Services: com.marie.mp3player.BackgroundService
D/PackageManager( 96): Activities: com.marie.mp3player.MP3Player com.marie.mp3player.PlayAudio
I/ActivityManager( 96): Force stopping package com.marie.mp3player uid=10091
W/PackageManager( 96): Code path for pkg : com.marie.mp3player changing from /data/app/com.marie.mp3player-2.apk to /data/app/com.marie.mp3player-1.apk
W/PackageManager( 96): Resource path for pkg : com.marie.mp3player changing from /data/app/com.marie.mp3player-2.apk to /data/app/com.marie.mp3player-1.apk
I/installd( 70): move /data/dalvik-cache/data@app@com.marie.mp3player-1.apk@classes.dex -> /data/dalvik-cache/data@app@com.marie.mp3player-1.apk@classes.dex
D/PackageManager( 96): New package installed in /data/app/com.marie.mp3player-1.apk
I/ActivityManager( 96): Force stopping package com.marie.mp3player uid=10091
D/dalvikvm( 96): GC_EXPLICIT freed 842K, 41% free 6421K/10759K, external 2424K/3027K, paused 106ms
D/dalvikvm( 192): GC_EXPLICIT freed 16K, 45% free 4617K/8327K, external 15977K/17649K, paused 67ms
D/dalvikvm( 158): GC_EXPLICIT freed 525K, 54% free 3151K/6791K, external 2480K/3071K, paused 49ms
I/ActivityManager( 96): Start proc com.appspot.swisscodemonkeys.apps for broadcast com.appspot.swisscodemonkeys.apps/.PackageReceiver: pid=17753 uid=10084 gids={3003}
I/ActivityThread(17753): Pub appbrain.SuggestionProvider: com.appspot.swisscodemonkeys.apps.search.SearchSuggestionSampleProvider
D/dalvikvm(11468): GC_EXPLICIT freed 2K, 49% free 2965K/5767K, external 1625K/2137K, paused 314ms
I/ActivityManager( 96): Start proc com.noshufou.android.su for broadcast com.noshufou.android.su/.UninstallReceiver: pid=17761 uid=10056 gids={1015, 3003}
D/dalvikvm( 96): GC_EXPLICIT freed 273K, 41% free 6367K/10759K, external 2424K/3027K, paused 101ms
I/installd( 70): unlink /data/dalvik-cache/data@app@com.marie.mp3player-2.apk@classes.dex
D/AndroidRuntime(17736): Shutting down VM
D/dalvikvm(17736): GC_CONCURRENT freed 101K, 72% free 296K/1024K, external 0K/0K, paused 0ms+1ms
D/jdwp (17736): Got wake-up signal, bailing out of select
D/dalvikvm(17736): Debugger has detached; object registry had 1 entries
I/ActivityManager( 96): Start proc com.android.voicedialer for broadcast com.android.voicedialer/.VoiceDialerReceiver: pid=17770 uid=10048 gids={3002}
D/VoiceDialerReceiver(17770): onReceive Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.marie.mp3player flg=0x10000000 cmp=com.android.voicedialer/.VoiceDialerReceiver (has extras) }
V/RecognizerEngine(17770): deleteCachedGrammarFiles /data/data/com.android.voicedialer/files/openentries.txt
I/ActivityManager( 96): Start proc com.android.vending for broadcast com.android.vending/.PackageMonitorReceiver: pid=17779 uid=10046 gids={1015, 3003}
D/dalvikvm( 67): GC_EXPLICIT freed 11K, 50% free 2717K/5379K, external 1625K/2137K, paused 94ms
D/dalvikvm( 67): GC_EXPLICIT freed <1K, 50% free 2717K/5379K, external 1625K/2137K, paused 81ms
I/ActivityThread(17779): Pub com.android.vending.SuggestionsProvider: com.android.vending.SuggestionsProvider
D/vending (17779): [1] VendingApplication.onCreate(): Resetting ServiceLocator from app
D/dalvikvm( 67): GC_EXPLICIT freed <1K, 50% free 2717K/5379K, external 1625K/2137K, paused 93ms
D/InstallReceiver(17761): com.marie.mp3player
I/ActivityManager( 96): Start proc com.google.android.partnersetup for broadcast com.google.android.partnersetup/.AppInstalledReceiver: pid=17791 uid=10021 gids={}
D/AndroidRuntime(17783):
D/AndroidRuntime(17783): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
D/AndroidRuntime(17783): CheckJNI is OFF
D/dalvikvm(17783): creating instr width table
D/GTalkService( 211): handlePackageInstalled: re-initialize providers
D/GTalkService( 211): [RawStanzaProvidersMgr] ##### searchProvidersFromIntent
D/GTalkService( 211): [RawStanzaProvidersMgr] no intent receivers found
D/VoiceDialerReceiver(17770): onReceive Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.marie.mp3player flg=0x10000000 cmp=com.android.voicedialer/.VoiceDialerReceiver (has extras) }
V/RecognizerEngine(17770): deleteCachedGrammarFiles /data/data/com.android.voicedialer/files/openentries.txt
I/ActivityManager( 96): Start proc com.google.android.googlequicksearchbox for broadcast com.google.android.googlequicksearchbox/.CorporaUpdateReceiver: pid=17798 uid=10022 gids={3003}
I/ActivityThread(17798): Pub com.google.android.googlequicksearchbox.shortcuts: com.google.android.googlequicksearchbox.ShortcutsProvider
I/ActivityThread(17798): Pub com.google.android.googlequicksearchbox.google: com.google.android.googlequicksearchbox.google.GoogleSuggestionProvider
I/ActivityManager( 96): Start proc com.google.android.apps.maps:FriendService for broadcast com.google.android.apps.maps/com.google.googlenav.friend.android.ServiceReceiver: pid=17812 uid=10033 gids={3003, 1015}
D/AndroidRuntime(17783): Calling main entry com.android.commands.am.Am
I/ActivityManager( 96): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.marie.mp3player/.MP3Player } from pid 17783
D/AndroidRuntime(17783): Shutting down VM
D/dalvikvm(17783): GC_CONCURRENT freed 102K, 69% free 320K/1024K, external 0K/0K, paused 0ms+0ms
D/jdwp (17783): Got wake-up signal, bailing out of select
D/dalvikvm(17783): Debugger has detached; object registry had 1 entries
I/ActivityManager( 96): Start proc com.marie.mp3player for activity com.marie.mp3player/.MP3Player: pid=17822 uid=10091 gids={}
I/AndroidRuntime(17783): NOTE: attach of thread 'Binder Thread #3' failed
I/ActivityManager( 96): Start proc com.google.android.apps.maps:NetworkLocationService for service com.google.android.apps.maps/com.google.android.location.internal.server.NetworkLocationService: pid=17830 uid=10033 gids={3003, 1015}
I/ActivityManager( 96): Displayed com.marie.mp3player/.MP3Player: +429ms
I/ActivityManager( 96): Start proc com.noinnion.android.greader.readerpro for broadcast com.noinnion.android.greader.readerpro/.OnUpgradeReceiver: pid=17831 uid=10070 gids={3003, 1015}
V/RenderScript_jni( 192): surfaceDestroyed
I/ActivityThread(17831): Pub com.noinnion.android.greader.readerpro: com.noinnion.android.greader.readerpro.ReaderProvider
D/InternalNlpService(17830): onCreate
D/NetworkLocationServiceThread(17830): start monitoring enabled
D/NetworkLocationServiceThread(17830): updateState
D/NetworkLocationServiceThread(17830): Creating RealOs
D/vending (17779): [11] LocalAssetCache.updateOnePackage(): No local info for com.marie.mp3player
D/szipinf (17830): Initializing inflate state
D/szipinf (17830): Initializing zlib to inflate
D/vending (17779): [12] LocalAssetCache.updateOnePackage(): No local info for com.marie.mp3player
D/dalvikvm(17830): GC_CONCURRENT freed 460K, 43% free 3851K/6727K, external 1625K/2137K, paused 2ms+3ms
D/WifiLocator(17830): Too many cache misses. Need server request. hasLocation=0 noLocation=1 cacheMiss=2
I/System.out(17830): [INFO:1747]: f: Running flush
I/System.out(17830): [INFO:1761]: f: Sending payload [bytes=300]
I/System.out(17830): [INFO:6772]: f: Running flush
I/System.out(17830): [INFO:6761]: f: Running delayed flush
I/ActivityManager( 96): Start proc org.my_pod.mypod for service org.my_pod.mypod/net.robmunro.mypod.UpdateFeedsService: pid=17853 uid=10080 gids={3003, 1015}
I/ActivityThread(17853): Pub org.my_pod.mypod: net.robmunro.mypod.util.MyPodContentProvider
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +297ms
W/KeyCharacterMap(17822): No keyboard for id 131074
W/KeyCharacterMap(17822): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
D/MP3Player(17822): Stop the background Service
D/WifiLocator(17830): Too many cache misses. Need server request. hasLocation=0 noLocation=1 cacheMiss=2
E/GlsClient-query(17830): requestFailed
E/GlsClient-query(17830): ay.g
E/GlsClient-query(17830): at ay.d.t(Unknown Source)
E/GlsClient-query(17830): at ay.b.a(Unknown Source)
E/GlsClient-query(17830): at Z.b.g(Unknown Source)
E/GlsClient-query(17830): at Z.a.g(Unknown Source)
E/GlsClient-query(17830): at Z.d.run(Unknown Source)
E/GlsClient-query(17830): at aE.d.run(Unknown Source)
D/dalvikvm(13124): GC_EXPLICIT freed 2K, 50% free 2715K/5379K, external 1625K/2137K, paused 56ms
D/dalvikvm( 192): GC_EXPLICIT freed 88K, 44% free 4690K/8327K, external 16026K/17649K, paused 85ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +305ms
D/MP3Player(17822): Stop the background Service
D/dalvikvm(17830): GC_CONCURRENT freed 1201K, 51% free 3612K/7239K, external 1625K/2137K, paused 3ms+3ms
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/System.out(17830): [INFO:50519]: f: Response [http=200,length=147]
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +307ms
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +255ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +302ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +296ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +294ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
E/(Messenger)messenger: (17822): NullPointerException
W/System.err(17822): java.lang.NullPointerException
W/System.err(17822): at com.marie.mp3player.BackgroundService$ServiceWorker.run(BackgroundService.java:65)
W/System.err(17822): at java.lang.Thread.run(Thread.java:1019)
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +278ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
E/(Messenger)messenger: (17822): NullPointerException
W/System.err(17822): java.lang.NullPointerException
W/System.err(17822): at com.marie.mp3player.BackgroundService$ServiceWorker.run(BackgroundService.java:65)
W/System.err(17822): at java.lang.Thread.run(Thread.java:1019)
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +282ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +307ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +284ms
D/MP3Player(17822): Stop the background Service
I/ActivityManager( 96): Starting: Intent { cmp=com.marie.mp3player/.PlayAudio (has extras) } from pid 17822
I/handleMessge(17822): songNum: 10
I/ActivityManager( 96): Displayed com.marie.mp3player/.PlayAudio: +291ms
有人建议我添加NullPointerException发生的代码。很重要。事实上,这是发生异常的整个线程,标有箭头和星号:
/*
* This is the ServiceWorker thread that calls messenger to pass messages
* and data to the PlayAudio activity.
*/
class ServiceWorker implements Runnable
{
public void run() {
// do background processing here... a simple message for now
// send a message to the handler defined in the PlayAudio
try {
Message msg1 = Message.obtain();
msg1.obj = "Song";
msg1.arg1 = song;
if (messenger == null) Log.e("(Messenger)messenger: ", "NullPointerException");
messenger.send(msg1); // <== *** EXCEPTION OCCURS HERE ***
} catch (RemoteException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
// stop the service when done...
// BackgroundService.this.stopSelf();
// Or use the unbindBtn in the MP3Player activity.
}
}
如果有人在这里看到一个错误,有时会导致我的Message实例为null,我肯定会欣赏答案。
答案 0 :(得分:1)
玛丽,假设你的其他服务与你的另一个问题一样。以下是发生的事情并导致您的NPE。
onCreate
中,您创建并启动线程,但是您使用onStart
方法提取信使。如果您的worker方法在onStart
之前执行,则会获得NPE。它们的顺序是随机的,所以有时你会得到NPE而有时候却没有。