从Java回调机制分析Android动态加载布局过程中出现的IllgalStateException

来源:互联网 发布:手机淘宝货到付款骗局 编辑:程序博客网 时间:2024/06/03 04:18
先说说自己对回调的理解吧。
1.什么是回调?指出某个特定事件发生时应该采取的动作,见《Java核心技术:卷一》
2.接触过的回调方法:Android 对控件注册点击监听:button.setOnClickListener(OnClickListener l)。  传入一个OnClickListener(接口实现类)类型的参数(在此类中实现接口中定义的回调方法onClick(View v)),  当点击事件发生时,经过系统的事件传递机制,会被监听到,然后调用接口实现类中设置好的的onClick(View v)方法,做出响应。  该响应方法,在接口中声明,在接口实现类中定义,即onClick(View v)方法,就是回调方法。  套用定义:点击事件发生时采取的动作(即点击事件的回调方法)是onClick(View v)方法
   我是一个Android初学者,目前进度到UI。最近在练习自定义对话框,动态加载对话框布局文件,遇到了IllgalStateException异常,代码如下:
button_user_alert.setOnClickListener(new OnClickListener() {//放在这里定义程序会崩溃,抛出IllgalStateExceptionView view = View.inflate(DialogComponentTest.this, R.layout.user_dialog, null);final EditText userName = (EditText) view.findViewById(R.id.edit_text_name);final EditText passWord = (EditText) view.findViewById(R.id.edit_text_password);@Overridepublic void onClick(View v) {//View view = View.inflate(DialogComponentTest.this, R.layout.user_dialog, null);//final EditText userName = (EditText) view.findViewById(R.id.edit_text_name);//final EditText passWord = (EditText) view.findViewById(R.id.edit_text_password);new AlertDialog.Builder(DialogComponentTest.this).setView(view).setPositiveButton("取消", null).setNegativeButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String strUserName = userName.getText().toString();String strPassWord = passWord.getText().toString();Toast.makeText(DialogComponentTest.this,strUserName +" : "+strPassWord, 0).show();}}).show();}});
    我在看到这样的异常的信息(同一个子类对象对应对个父类对象)也不是太理解,试图从程序运行过程分析,但是由于对回调机制理解不够,也摸不清程序的运行过程。经过查找资料,确定了以上代码的执行顺序:
    1. 向button_user_alert注册监听:方法setOnClickListener(OnClickListener l);
    2. 创建注册监听方法中的OnClickListener接口实现类的对象
    3. 当接收到点击事件时,调用接口实现类中设置好的的onClick(View v)方法。
   上面的代码在第二步,创建了对话框的子视图对象,在回调方法中构建对话框时加载子视图。第一次点击时,程序能正常运行,如果再次点击,抛出异常,程序崩溃。原因是第二次点击后,再次调用onClick(View v)方法,重新构建对话框,加载在注册监听时就创建好的子View(还是第一次点击时的子view),这就造成了同一个子View对应多个父View。
   最后,关于回调,在不考虑异步的情况下,在这里用HarryPotter中修眼镜的桥段举个例子,HarryPotter的眼睛碎了(事件),让赫敏修复,赫敏使用魔法修复好,交HarryPotter。
   问题分析:事件:Harrypotter的眼镜碎了,动作:HermioneGranger修眼镜  那么回调方法是HermioneGranger的修眼镜方法
//定义修眼镜接口public interface RescoverGlass {//HarryPotter类型参数的修眼镜方法void rescover(HarryPotter h);}

//定义HermioneGranger类实现修眼镜接口public class HermioneGranger implements RescoverGlass{@Override//重写修眼镜方法,调用HarryPotter类中的getName方法public void rescover(HarryPotter h) {// TODO 自动生成的方法存根System.out.println("Rescover it");System.out.println(h.getName()+"here you are!");}}
//定义HarryPotter类public class HarryPotter {//private static final String NAME="Harry potter";//以修眼镜接口实现类类型为参数,调用实现类的修眼镜方法public void breakMyGlasses(RescoverGlass r){System.out.println("My glasses are broken!");r.rescover(this);}public String getName(){return NAME;}}

//测试,使用匿名内部类对象实现,类似于setOnClickListenerpublic class CallBackTestUseInnerClass {public static void main(String[] args) {HarryPotter harry = new HarryPotter();//创建一个harryharry.breakMyGlasses(new RescoverGlass() {@Overridepublic void rescover(HarryPotter h) {// TODO 自动生成的方法存根System.out.println("Rescover it!");System.out.println(h.getName()+" , here you are!");}});//打碎harry的眼镜,让hermione知道
//最终实现了只要眼镜碎了的事件发生了,就会调用回调方法将眼镜修好}}


        以上,是自学过程中对回调的一点理解,我的Android和Java是一起看的,非科班出身,基础不好,如果理解有误还忘指正,谢谢。

1 0
原创粉丝点击