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在项目中使用到了ActivityGroup在字activity弹出dialog报错总计我们在ActivityGroup或者TabActivity中的子Activity创建Dialog若使用以下的代码progressDialog=newProgressDialog(XXX.this)创建就会出现如下Exception:android.view.WindowManagerBadTokenException: Unable to add window – token android.app.LocalActivityManager$LocalActivityRecord@43e5b158 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 }
第二种方法简单有效