Android常见问题1:窗体泄露(1)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android常见问题1:窗体泄露(1),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8185字,纯文字阅读大概需要12分钟。
内容图文
今天学习对话框AlertDialog,写一个Demo,需求是:只有一个Activitty,在这个Activity中只有一个按钮Button,当点击按钮Button时,弹出对话框,提示是否关闭该Activity,退出程序(只有一个界面).
MainActivity源码:
1 package com.my.day22_my_dialog1; 2 3 import android.os.Bundle; 4 import android.view.KeyEvent; 5 import android.view.View; 6 import android.view.View.OnClickListener; 7 import android.widget.Button; 8 import android.app.Activity; 9 import android.app.AlertDialog; 10 import android.app.Dialog; 11 import android.content.DialogInterface; 12 13 public class MainActivity extends Activity { 14private Button bt; 15private AlertDialog dialog; 1617 @Override 18protectedvoid onCreate(Bundle savedInstanceState) { 19super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 2122 initDialog(); 2324 bt = (Button) findViewById(R.id.bt); 25 bt.setOnClickListener(new OnClickListener() { 2627 @Override 28publicvoid onClick(View v) { 29 dialog.show(); 30 } 31 }); 32 } 3334privatevoid initDialog() { 35//创建对话框创建器对象36 AlertDialog.Builder builder = new AlertDialog.Builder(this); 3738 builder.setTitle("关闭?"); 39 builder.setIcon(R.drawable.ic_launcher); 40 builder.setMessage("关闭该Activity?"); 41 builder.setCancelable(false);//设置点击对话框之外的内容是否取消对话框42 builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { 4344 @Override 45publicvoid onClick(DialogInterface dialog, int which) { 46 finish(); 47 } 48 }); 4950 builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { 5152 @Override 53publicvoid onClick(DialogInterface dialog, int which) { 54 dialog.dismiss(); 55 } 56 }); 575859 dialog = builder.create(); 60 } 61 }
activity_man.xml布局文件:
1 < RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android" 2 xmlns:tools ="http://schemas.android.com/tools" 3 android:layout_width ="match_parent" 4 android:layout_height ="match_parent" 5 android:paddingBottom ="@dimen/activity_vertical_margin" 6 android:paddingLeft ="@dimen/activity_horizontal_margin" 7 android:paddingRight ="@dimen/activity_horizontal_margin" 8 android:paddingTop ="@dimen/activity_vertical_margin" 9 tools:context =".MainActivity" > 10 11 < Button 12 android:id ="@+id/bt" 13 android:layout_width ="match_parent" 14 android:layout_height ="wrap_content" 15 android:text ="对话框" /> 16 17 </ RelativeLayout >
现在增加需求:要求点击返回键时,关闭该Activity。
方式1:
重写public boolean onKeyDown(int keyCode, KeyEvent event)方法,适合各种按键事件,可以说比较通用。
修改后的MainActivity源码:
1 package com.my.day22_my_dialog1; 2 3 import android.os.Bundle; 4 import android.view.KeyEvent; 5 import android.view.View; 6 import android.view.View.OnClickListener; 7 import android.widget.Button; 8 import android.app.Activity; 9 import android.app.AlertDialog; 10 import android.app.Dialog; 11 import android.content.DialogInterface; 12 13 public class MainActivity extends Activity { 14private Button bt; 15private AlertDialog dialog; 1617 @Override 18protectedvoid onCreate(Bundle savedInstanceState) { 19super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 2122 initDialog(); 2324 bt = (Button) findViewById(R.id.bt); 25 bt.setOnClickListener(new OnClickListener() { 2627 @Override 28publicvoid onClick(View v) { 29 dialog.show(); 30 } 31 }); 32 } 3334privatevoid initDialog() { 35//创建对话框创建器对象36 AlertDialog.Builder builder = new AlertDialog.Builder(this); 3738 builder.setTitle("关闭?"); 39 builder.setIcon(R.drawable.ic_launcher); 40 builder.setMessage("关闭该Activity?"); 41 builder.setCancelable(false);//设置点击对话框之外的内容是否取消对话框42 builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { 4344 @Override 45publicvoid onClick(DialogInterface dialog, int which) { 46 finish(); 47 } 48 }); 4950 builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { 5152 @Override 53publicvoid onClick(DialogInterface dialog, int which) { 54 dialog.dismiss(); 55 } 56 }); 575859 dialog = builder.create(); 60 } 6162//下面为增加的方法63 @Override 64publicboolean onKeyDown(int keyCode, KeyEvent event) { 65// TODO Auto-generated method stub66if(keyCode == KeyEvent.KEYCODE_BACK) 67 dialog.show(); 68returnsuper.onKeyDown(keyCode, event); 69 } 7071 }
上述方法没什么太大的问题。
方法二:Activity中有一个回调方法public void onBackPressed(),从名字可以知道是当按下返回键执行的方法,那么依然需求是当按下返回键就弹出对话框,用户选择是否退出Activity,所以很自然的可以重写这个方法,让Activity被销毁,所以自然而然的有了下面的MainActivity源代码:
1 package com.my.day22_my_dialog1; 2 3 import android.os.Bundle; 4 import android.view.KeyEvent; 5 import android.view.View; 6 import android.view.View.OnClickListener; 7 import android.widget.Button; 8 import android.app.Activity; 9 import android.app.AlertDialog; 10 import android.app.Dialog; 11 import android.content.DialogInterface; 12 13 public class MainActivity extends Activity { 14private Button bt; 15private AlertDialog dialog; 1617 @Override 18protectedvoid onCreate(Bundle savedInstanceState) { 19super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 2122 initDialog(); 2324 bt = (Button) findViewById(R.id.bt); 25 bt.setOnClickListener(new OnClickListener() { 2627 @Override 28publicvoid onClick(View v) { 29 dialog.show(); 30 } 31 }); 32 } 3334privatevoid initDialog() { 35//创建对话框创建器对象36 AlertDialog.Builder builder = new AlertDialog.Builder(this); 3738 builder.setTitle("关闭?"); 39 builder.setIcon(R.drawable.ic_launcher); 40 builder.setMessage("关闭该Activity?"); 41 builder.setCancelable(false);//设置点击对话框之外的内容是否取消对话框42 builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { 4344 @Override 45publicvoid onClick(DialogInterface dialog, int which) { 46 finish(); 47 } 48 }); 4950 builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { 5152 @Override 53publicvoid onClick(DialogInterface dialog, int which) { 54 dialog.dismiss(); 55 } 56 }); 575859 dialog = builder.create(); 60 } 6162//下面为增加的方法63 @Override 64publicvoid onBackPressed() { 65// TODO Auto-generated method stub66super.onBackPressed(); 67 dialog.show(); 68 } 69 }
然而执行的结果是程序直接崩溃,LogCat捕获的信息如下图:
以上出错信息第一行可以得到关键信息:***Activity has leaked Window .... (leak:泄露)
原因是:系统执行onBackPressed()方法后,会继续回调Activity的onPause()、onStop()、onDestroy()等生命周期方法,当最后执行onDestroy()方法会,系统会销毁Activity,而此时Activity界面上显示的对话框依然存在,而对话框依赖的Activity对象已经不存在了,就会出现这种情况应用已经没有了Activity,而这个应用却存在一个对话框,且这个对话框是依赖之前存在的Activity,此时就出现了窗体泄露,程序崩溃。
在网上搜了很长时间,解决方式是:既然Activity最后肯定会执行onDestroy()方法,那么可以在onDestroy()中强制将对话框关闭,这样就解决了问题。
因此第二种方式MainActivity的完整源码:
package com.my.day22_my_dialog1; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; public class MainActivity extends Activity { private Button bt; private AlertDialog dialog; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initDialog(); bt = (Button) findViewById(R.id.bt); bt.setOnClickListener(new OnClickListener() { @Override publicvoid onClick(View v) { dialog.show(); } }); } privatevoid initDialog() { //创建对话框创建器对象 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("关闭?"); builder.setIcon(R.drawable.ic_launcher); builder.setMessage("关闭该Activity?"); builder.setCancelable(false);//设置点击对话框之外的内容是否取消对话框 builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override publicvoid onClick(DialogInterface dialog, int which) { finish(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override publicvoid onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); dialog = builder.create(); } //下面为增加的代码 @Override protectedvoid onDestroy() { // TODO Auto-generated method stubif(dialog!=null) dialog.dismiss(); super.onDestroy(); } @Override publicvoid onBackPressed() { // TODO Auto-generated method stubsuper.onBackPressed(); dialog.show(); } }
思考:如果采用这种方法,那么在onBackPressed()方法中的方法体不起作用,有没有对话框都无所谓,反正也不起作用,也没有达到需求:“当按下返回键时,出现对话框,选择确定后才会退出当前Activity,该方法只是解决了窗体泄露,而没有解决需求”,因为当你按下返回键,不管你有没有在出现的对话框上操作,系统会自动退出当前Activity。想要想一个办法,重写onBackPressed()等方法,出现对话框,用户做出选择,然后系统才决定是否退出该Activity。
未完,待续.
原文:http://www.cnblogs.com/enjoy-coding/p/4790144.html
内容总结
以上是互联网集市为您收集整理的Android常见问题1:窗体泄露(1)全部内容,希望文章能够帮你解决Android常见问题1:窗体泄露(1)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。