望尘轩中一盏茶

统计

留言簿

友情链接

阅读排行榜

评论排行榜

进度框按back键返回上一个activity(处理Leak Window)

场景描述:进入一个界面需要先去网络加载内容,浮出一个进度框提示正在加载中,这时如果按下back键返回,本意是返回上一个界面,而系统默认只是dismiss掉了进度框,需要再按一次back键才能返回上一个界面。现在想只按一次back键就返回上一个界面,催生了本次实验。具体实现参考代码:

首先继承ProgressDialog类,实现自己的进度框类,这里主要是为了在进度框处于焦点时,捕获其按键事件。具体代码如下:

public class MyDialog extends ProgressDialog {
    private Activity parentActivity;
    public MyDialog(Context context) {
	super(context);
	parentActivity = (Activity) context;
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
	if(parentActivity != null) {
            return parentActivity.onKeyDown(keyCode, event);
	}
	return super.onKeyDown(keyCode, event);
    }
}

这里在进度框处于焦点状态按下back键时,调用了打开进度框的activity的按键监听事件,将相关处理交给activity进行处理。Activity的实现代码如下:

public class DialogTestActivity extends Activity {

	private MyDialog pDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        showLoadingDialog();
    }

    private void showLoadingDialog() {
    	pDialog = new MyDialog(this);
    	pDialog.setMessage("正在加载中...");
		pDialog.setCancelable(true);
		pDialog.show();
	}

	private void dismissLoadingDialog() {
		if(pDialog != null && pDialog.isShowing()) {
			pDialog.dismiss();
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		finish();
		return super.onKeyDown(keyCode, event);
	}

	@Override
	protected void onDestroy() {
		dismissLoadingDialog();
		super.onDestroy();
	}
}

这里在onKeyDown实现里直接调用了Activity的finish()方法来结束Activity,如果不调用此方法就不能实现想要的效果;并在onDestroy()方法里调用了关掉进度框的操作,这里是非常必要的。虽然不调用程序一样会正常返回,但是在logcat中会看到这里有问题,具体信息如下:

12-20 15:24:51.315: E/WindowManager(6759): Activity com.jade.dialog.DialogTestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f493c8 that was originally added here
12-20 15:24:51.315: E/WindowManager(6759): android.view.WindowLeaked: Activity com.jade.dialog.DialogTestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f493c8 that was originally added here
12-20 15:24:51.315: E/WindowManager(6759): 	at android.view.ViewRoot.(ViewRoot.java:247)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.view.Window$LocalWindowManager.addView(Window.java:424)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.Dialog.show(Dialog.java:241)
12-20 15:24:51.315: E/WindowManager(6759): 	at com.jade.dialog.DialogTestActivity.showLoadingDialog(DialogTestActivity.java:23)
12-20 15:24:51.315: E/WindowManager(6759): 	at com.jade.dialog.DialogTestActivity.onCreate(DialogTestActivity.java:15)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.ActivityThread.access$2300(ActivityThread.java:125)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.os.Handler.dispatchMessage(Handler.java:99)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.os.Looper.loop(Looper.java:123)
12-20 15:24:51.315: E/WindowManager(6759): 	at android.app.ActivityThread.main(ActivityThread.java:4627)
12-20 15:24:51.315: E/WindowManager(6759): 	at java.lang.reflect.Method.invokeNative(Native Method)
12-20 15:24:51.315: E/WindowManager(6759): 	at java.lang.reflect.Method.invoke(Method.java:521)
12-20 15:24:51.315: E/WindowManager(6759): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-20 15:24:51.315: E/WindowManager(6759): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-20 15:24:51.315: E/WindowManager(6759): 	at dalvik.system.NativeStart.main(Native Method)

出现上述问题的原因是在Activity调用finish()方法结束自己的时候,进度框尚未关闭。当然也有另外一种方案,就是修改MyDialog中按键处理部分,首先dismiss()自己,然后再调用activity的按键事件处理方法。具体代码如下:

public boolean onKeyDown(int keyCode, KeyEvent event) {
	if(parentActivity != null) {
		dismiss(); //在这里自己关掉自己喽~
		return parentActivity.onKeyDown(keyCode, event);
	}
	return super.onKeyDown(keyCode, event);
}

版权声明

文章编辑:玉盏掬清茶 ( 点击名字查看他发布的更多文章 )
原始站点:玉盏掬清茶(www.58bxj.com)
原文标题:进度框按back键返回上一个activity(处理Leak Window)
原文链接:http://www.58bxj.com/art/299.html

标签: 

posted on 2011-12-20 15:38 wzhongyu 阅读(1929) 评论(0)  编辑  收藏 所属分类: Java学习


只有注册用户登录后才能发表评论。


网站导航:
 
我的便捷门:综合频道 数码频道 商城频道 电器频道 男人频道 女人频道 居家玩具 美容频道 饰品鞋包 食品频道 台湾馆频道