android-----ANR
2015-08-08 12:02
621 查看
今天接触到Android的ANR,ANR(application not response)即应用程序没有响应。
先上一段代码:
布局代码:
![](http://img.blog.csdn.net/20150808111007309?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
为什么会产生这样的原因了?原来主线程(UI线程)需要做很多重要的事情,如响应点击事件、更新UI。
如果在主线程中阻塞过长的时间,应用程序就会无响应。因此,为了避免这种情况的发生就需要:
所有耗时的操作都应该放在子线程中完成。
此外,出现ANR还与Android 的版本有关,在Android4.0以上的版本在设计时就会检查主线程的操作,若主线程耗时过长就会直接出现ANR,但在Android4.0以下就没有这种情况,可能是当时设计时并没有考虑到这种情况。
下面来看看这个示例
布局文件代码:
Src代码:
![](http://img.blog.csdn.net/20150808110936379?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
程序是能够正常运行的
再用Android4.3的模拟器运行程序,结果如下所示:
![](http://img.blog.csdn.net/20150808111355996?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
原因:访问网络的操作只能在子线程中执行,若是在主线程中执行,程序就会弹出ANR
并报以下的警告:
![](http://img.blog.csdn.net/20150808111931189?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
将代码更改如下:
![](http://img.blog.csdn.net/20150808120032669?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
程序就可以正常运行了。
先上一段代码:
布局代码:
<span style="font-size:18px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <Button android:onClick="click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="点我" /> </RelativeLayout></span>java代码:
<span style="font-size:18px;">public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click(View v){ try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } } }</span>运行应用程序,结果如下所示:
为什么会产生这样的原因了?原来主线程(UI线程)需要做很多重要的事情,如响应点击事件、更新UI。
如果在主线程中阻塞过长的时间,应用程序就会无响应。因此,为了避免这种情况的发生就需要:
所有耗时的操作都应该放在子线程中完成。
此外,出现ANR还与Android 的版本有关,在Android4.0以上的版本在设计时就会检查主线程的操作,若主线程耗时过长就会直接出现ANR,但在Android4.0以下就没有这种情况,可能是当时设计时并没有考虑到这种情况。
下面来看看这个示例
布局文件代码:
<span style="font-size:18px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <ImageView android:id="@+id/iv" android:layout_weight="20" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <!-- android:hint="请输入图片路径" --> <EditText android:id="@+id/et_path" android:text="http://c.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4ce3024eb2d42a6059252da69d.jpg" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/bt" android:onClick="openImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="浏览"/> </LinearLayout></span>
Src代码:
<span style="font-size:18px;">public class MainActivity extends Activity { private ImageView iv; private EditText et_path; private Button bt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv=(ImageView) findViewById(R.id.iv); et_path=(EditText) findViewById(R.id.et_path); bt=(Button) findViewById(R.id.bt); } public void openImage(View v){ String path=et_path.getText().toString().trim(); if(TextUtils.isEmpty(path)){ Toast.makeText(this, "图片路径不能为空", 0).show(); }else{ try { URL url=new URL(path); //根据URL发送http请求 HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //设置请求方式 conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("Connection", "Keep-Alive"); int code=conn.getResponseCode(); if(code==200){ InputStream is=conn.getInputStream(); Bitmap bitmap= BitmapFactory.decodeStream(is); iv.setImageBitmap(bitmap); }else{ Toast.makeText(this, "显示图片失败", 0).show(); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "获取图片失败", 0).show(); } } } }</span>先使用Android2.2模拟器运行程序,结果如下所示:
程序是能够正常运行的
再用Android4.3的模拟器运行程序,结果如下所示:
原因:访问网络的操作只能在子线程中执行,若是在主线程中执行,程序就会弹出ANR
并报以下的警告:
将代码更改如下:
public class MainActivity extends Activity { protected static final int CHANGE_UI = 1; private ImageView iv; private EditText et_path; //主线程创建一个消息处理器 <span style="color:#FF0000;">private Handler handler=new Handler(){ public void handleMessage(Message msg){ if(msg.what==CHANGE_UI){ Bitmap bitmap=(Bitmap) msg.obj; iv.setImageBitmap(bitmap); } } };</span> @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv=(ImageView) findViewById(R.id.iv); et_path=(EditText) findViewById(R.id.et_path); } public void openImage(View v){ final String path=et_path.getText().toString().trim(); if(TextUtils.isEmpty(path)){ Toast.makeText(this, "图片路径不能为空", 0).show(); }else{ <span style="color:#FF0000;">new Thread(){ public void run(){ try { URL url=new URL(path); //根据URL发送http请求 HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //设置请求方式 conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("Connection", "Keep-Alive"); int code=conn.getResponseCode(); if(code==200){ InputStream is=conn.getInputStream(); Bitmap bitmap= BitmapFactory.decodeStream(is); //iv.setImageBitmap(bitmap); //告诉主线程一个消息:帮我改界面 内容:bitmap Message msg=new Message(); msg.what=CHANGE_UI; msg.obj=bitmap; handler.sendMessage(msg); }else{ Toast.makeText(MainActivity.this, "显示图片失败", 0).show(); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "获取图片失败", 0).show(); } } }.start();</span> } } }再次运行Android4.3的模拟器,结果如下所示:
程序就可以正常运行了。
相关文章推荐
- [Android Studio 权威教程]AS 中配置强大的版本管理系统(Git、SVN、等)
- [Android Studio 权威教程]AS构建系统-Gradle
- [Android Studio 权威教程]断点调试和高级调试
- [Android Studio 权威教程]AS添加第三方库的6种方式(Jar,module,so等)
- [Android Studio 权威教程]最实用的快捷键
- [Android Studio 权威教程]Android Studio 三种添加插件的方式
- [Android Studio 权威教程]配置出“NB”的Android Studio
- [Android Studio 权威教程]离线配置SDK,创建第一个AS项目
- [Android Studio 权威教程]Windows下安装Android Studio
- [Android Studio 权威教程]Mac下安装Android Studio
- android 当不点击的时候不会出现键盘,点击后出现键盘
- adb停止工作解决
- android出现注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: 某些输入文件使用了未经检查或不安全的操作。 注
- AsyncTask异步加载
- Android Studio插件和工具
- Android兼容性测试框架(CTS)手册
- android USB OTG功能实现
- Android单元测试初探——Instrumentation
- Android之——屏幕适配px转dip
- android平台获取手机IMSI,IMEI ,序列号,和 手机号的方法