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

先说说自己对回调的理解吧。
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() {
			//放在这里定义程序会崩溃,抛出IllgalStateException
			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);
			@Override
			public 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() {
					
					@Override
					public 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;
	}
}

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


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值