進度框按back鍵返回上一個activity(處理Leak Window)
場景描述:進入一個界面需要先去網絡加載內容,浮出一個進度框提示正在加載中,這時如果按下back鍵返回,本意是返回上一個界面,而系統默認只是dismiss掉了進度框,需要再按一次back鍵才能返回上一個界面?,F在想只按一次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 閱讀(1960) 評論(0) 編輯 收藏 所屬分類: Java學習