1. 程式人生 > >ActivityGroup子Activity建立Dialog:android.view.WindowManager$BadTokenException和IllegalArgumentException

ActivityGroup子Activity建立Dialog:android.view.WindowManager$BadTokenException和IllegalArgumentException

ActivityGroup中的子Activity建立Dialog:android.view.WindowManager B a d T o k e n

E x c e p t i o n
使 A c t i v
i t y G r o u p a c t i v i t y d i a l o g A c t i v i t y G r o u p T a b A c t i v i t y A c t i v i t y D i a l o g 使 p r o g r e s s D i a l o g = n e w P r o g r e s s D i a l o g ( X X X . t h i s ) E x c e p t i o n : a n d r o i d . v i e w . W i n d o w M a n a g e r BadTokenException 在專案中使用到了ActivityGroup 在字activity彈出dialog報錯 總計 我們在ActivityGroup或者TabActivity中的子Activity建立Dialog若使用以下的程式碼 progressDialog = new ProgressDialog(XXX.this) 建立就會出現如下Exception: android.view.WindowManager BadTokenException: Unable to add window – token [email protected] is not valid; is your activity running?
而該使用:
progressDialog = new ProgressDialog(getParent())
若ActivityGroup中巢狀ActivityGroup,巢狀多少就該使用多少個getParent()。
為什麼要使用getParent我們可以從柯元旦的《Android核心剖析》中第十章”Ams內部原理“中的ActivityGroup的內部機制來理解:
TabActivity的父類是ActivityGroup,而ActivityGroup的父類是Activity。因此從Ams的角度來看,ActivityGroup與普通的Activity沒有什麼區別,
其生命週期包括標準的start,stop,resume,destroy等,而且系統中只允許同時允許一個ActivityGroup.但ActivityGroup內部有一個重要成員變數,其型別為LocalActivityManager,
該類的最大特點在於它可以訪問應用程序的主類,即ActivityThread類。Ams要啟動某個Activity或者贊同某個Activity都是通過ActivityThread類執行的,而LocalActivityManager
類就意味著可以通過它來裝載不同的Activity,並控制Activity的不同的狀態。注意,這裡是裝載,而不是啟動,這點很重要。所謂的啟動,一般是指會建立一個程序(如果所在的應用經常還不存在)
執行該Activity,而裝載僅僅是指把該Activity作為一個普通類進行載入,並建立一個該類的物件而已,而該類的任何函式都沒有被執行。裝載Activity物件的過程對AmS來講是完全不可見的,
那些嵌入的Activity僅僅貢獻了自己所包含的Window視窗而已。而子Activity的不同狀態是通過moveToState來處理的。

java.lang.IllegalArgumentException: pointerIndex out of range
// java.lang.IllegalArgumentException:
pointerIndexoutofrange
//atandroid.view.MotionEvent.nativeGetAxisValue(NativeMethod)
//atandroid.view.MotionEvent.getY(MotionEvent.java:1989)
//atandroid.widget.ScrollView.onTouchEvent(ScrollView.java:575)
//atandroid.view.View.dispatchTouchEvent(View.java:5541)
// at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1963)
// at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1724)
網上說明:
The edge slop code could violate invariants of ScaleGestureDetector,
such as the assumption that if an ACTION_POINTER_DOWN is observed
or if getPointerCount() >= 2, then there must be at least two
active pointers to choose from. But due to the edge slop handling,
it was possible for findNewActiveIndex to return -1 in this
case, resulting in a crash.
解決方案:

在做多點觸控放大縮小,操作自己所繪製的圖形時發生這個異常,
如果是操作圖片的放大縮小多點觸控不會出現這個錯誤,這個BUG是安卓系統原因,所以第一種方案修改
frameworks\base\core\jni\android_view_MotionEvent.cpp
的android_view_MotionEvent_nativeGetAxisValue方法
註釋掉
if (!validatePointerIndex(env, pointerIndex, pointerCount)) {return 0;}
改完後需重新編譯整個系統,然後替換lib庫,重新編譯整個系統一般需要半個多小時,這個方法就比較麻煩了

第二種方法是:捕獲IllegalArgumentException(非法引數異常)異常 即如
1 private float spacing(MotionEvent event) {
2 try {
3 x = event.getX(0) - event.getX(1);
4 y = event.getY(0) - event.getY(1);
5 } catch (IllegalArgumentException e) {
6 // TODO Auto-generated catch block
7 e.printStackTrace();
8 }
第二種方法簡單有效