android - OnPause and OnStop() called immediately after starting activity -
i have activity needs turn screen on(if offed) when started. in oncreate, have:
this.getwindow().setflags( windowmanager.layoutparams.flag_keep_screen_on | windowmanager.layoutparams.flag_show_when_locked | windowmanager.layoutparams.flag_turn_screen_on, windowmanager.layoutparams.flag_keep_screen_on | windowmanager.layoutparams.flag_show_when_locked | windowmanager.layoutparams.flag_turn_screen_on);
using of wakelock in broadcasr receiver , able cause activity display whenever started broadcast receiver.
but problem strange, activity lifecycle calls in manner, onpause() , onresume after starting activity
- oncreate
- onstart
- onresume
- onpause
- onstop
- onstart
- onresume
so problem on start , on resume calling twice, on stop calling, want implement logic in onstop() but, such behavior app not work correctly.
edit
i found problem due flag flag_show_when_locked. , when device locked. , happens when device locked before activity starting.
p.s using alarm manager broadcast receiver, , starts activity broadcast receiver.
- let understand why lifecycle methods called multiple times.
here important code comment documented in activitythread, responsible executing activities of application process.
we accomplish going through normal startup (because activities expect go through onresume() first time run, before window displayed), , pausing it.
right after onresume
, activity window attached window manager , onattachedtowindow
invoked. if screen on, activity window focus , onwindowfocuschanged
invoked true
parameter. docs:
keep in mind onresume not best indicator activity visible user; system window such keyguard may in front. use onwindowfocuschanged(boolean) know activity visible user
in reported issue, screen if off. hence activity window not focus, results in activity's onpause
method getting called followed onstop
method, activity window not visible.
since windowmanager.layoutparams.flag_turn_screen_on
flag set on activity window, window manager service turns on screen using power manager api. following windowmanagerservice code:
public int relayoutwindow(...) { ... tobedisplayed = !win.isvisiblelw(); ... if (tobedisplayed) { ... if ((win.mattrs.flags & windowmanager.layoutparams.flag_turn_screen_on) != 0) { if (debug_visibility) slog.v(tag, "relayout window turning screen on: " + win); win.mturnonscreen = true; } ... if (mturnonscreen) { if (debug_visibility) slog.v(tag, "turning screen on after layout!"); mpowermanager.wakeup(systemclock.uptimemillis()); mturnonscreen = false; } ... }
after screen turns on onstart
, onpause
called again.
hence : oncreate - onstart - onresume - onpause - onstop - onstart - onpause
.
this can verified locking device , starting activity using adb
command or eclipse
.
- ideal solution
if start task in oncreate
need stop in ondestory
(if task still pending). onstart
onstop
, onresume
onpause
.
- workaround
if can't follow above protocol, can check status of activity window focus using haswindowfocus in onpause
method. activity window focus status true in onpause
. in scenarios screen off or screen on keyguard displayed, activity window focus false in onpause
.
boolean mfocusduringonpause; public void onpause() { super.onpause; mfocusduringonpause = haswindowfocus(); } public void onstop() { super.onstop(); if(mfocusduringonpause) { // normal scenario } else { // activity started when screen off / screen on keygaurd displayed } }
Comments
Post a Comment