onAttachedToWindow () 和 onDetachedFromWindow ()

protected void onAttachedToWindow()
This is called when the view is attached to a window. At this point it has a Surface and will start drawing. Note that this function is guaranteed to be called before onDraw(android.graphics.Canvas), however it may be called any time before the first onDraw – including before or after onMeasure(int, int).

如果你在自己的view中Override了這個方法。那麼我們最關注的是它什麼時候調用?

從開發文檔中我們可以看出,onAttachedToWindow是在第一次onDraw前調用的。也就是我們寫的View在沒有繪製出來時調用的,但只會調用一次。

比如,我們寫狀態欄中的時鐘的View,在onAttachedToWindow這方法中做初始化工作,比如註冊一些廣播等等……

與onAttachedToWindow 相反的則是這個方法:

protected void onDetachedFromWindow()
Since: API Level 1

This is called when the view is detached from a window. At this point it no longer has a surface for drawing.

開發文檔就簡單的兩句。也就是我們銷燬View的時候。我們寫的這個View不再顯示。

這時我們就在這個方法做一些收尾工作,如:取消廣播註冊等等。

究竟是如何的調用順序,我在播放界面的Activity中重寫了這2個方法,並在其中打印Log,下面我們來看一下運行效果。

onAttachedToWindow () onDetachedFromWindow ()

A:表示剛進入視頻播放頁面時執行的一系列。

B:表示點擊back鍵退出視頻播放頁面時執行的一些列操作

上面一個橢圓部分,表示播放視頻的初始化操作。

下面一個橢圓部分,表示播放視頻的銷燬操作,比如釋放資源。

由此可見,onAttachedToWindow在初始化視頻播放(既創建view)之前調用,

onDetachedFromWindow在退出視頻播放,銷燬資源(既銷燬view)之後調用。

在 Adroid2.1 和 Adroid2.2 設備上,如果 Activity 中使用到 ViewFlipper 控件,進行橫豎屏切換操作時會發生如下錯誤信息:

1 Program crashes, giving this crash log:
2
3 java.lang.IllegalArgumentException: Receiver not registered: android.widget.ViewFlipper1@44b6ab904atandroid.app.ActivityThread PackageInfo.forgetReceiverDispatcher(ActivityThread.java:667)
5 at android.app.ApplicationContext.unregisterReceiver(ApplicationContext.java:747)
6 at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:321)
7 at android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)
8 at android.view.View.dispatchDetachedFromWindow(View.java:5835)
9 at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1076)
10 at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
11 at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
12 at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
13 at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
14 at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1570)
15 at android.view.ViewRoot.doDie(ViewRoot.java:2556)
16 at android.view.ViewRoot.die(ViewRoot.java:2526)
17 at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:218)
18 at android.view.WindowLocalWindowManager.removeViewImmediate(Window.java:436)19atandroid.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3498)20atandroid.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3599)21atandroid.app.ActivityThread.access 2300(ActivityThread.java:119)
22 at android.app.ActivityThreadH.handleMessage(ActivityThread.java:1867)23atandroid.os.Handler.dispatchMessage(Handler.java:99)24atandroid.os.Looper.loop(Looper.java:123)25atandroid.app.ActivityThread.main(ActivityThread.java:4363)26atjava.lang.reflect.Method.invokeNative(NativeMethod)27atjava.lang.reflect.Method.invoke(Method.java:521)28atcom.android.internal.os.ZygoteInit MethodAndArgsCaller.run(ZygoteInit.java:860)
29 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
30 at dalvik.system.NativeStart.main(Native Method)

這是由於 onDetachedFromWindow() 莫名其妙地在 onAttachedToWindow() 之前被調用了。

先提供解決方案如下:

1.重載ViewFlipper的onDetachedFromWindow()方法,注意修改訪問修飾符爲public。

@Override

public void onDetachedFromWindow() {

  // 因爲該問題多發生於2.1或者2.2設備上,所以做此判斷,如果其他API Level也出現類似情況,只要修       //改這個地方即可。 

if (Build.VERSION.SDK_INT == 7) { 

    try {

        super.onDetachedFromWindow();

    } catch (IllegalArgumentException e) {

        Log.w(TAG, "Android project  issue 6191  workaround.");

        e.printStackTrace();

    } finally {

        super.stopFlipping();

    }

} else {

    super.onDetachedFromWindow();

}

}

若第一步不起作用,則在第一步的基礎上,緊接着進行第二步:

  1. 重載Activity的onDetachedFromWindow()在其中加入

@Override

public void onDetachedFromWindow() {

if (myFlipper != null) {

    myFlipper.onDetachedFromWindow();// 第一步中修飾符修改爲了public,這裏才能訪問到。

}

}

當然進行第二步的前提是,你已經重載了ViewFlipper的onDetachdFromWindow()方法,既第一步。

發佈了32 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章