之前的项目里要做一个异步更新UI的功能,可是结果出现了ANR,所以想写个demo来測试究竟是哪个地方出现了问题,结果发现原来的思路是没有问题,郁闷~~

如今这个demo 就是模拟项目里面 的步骤

1、接收到系统的广播(如今模拟为人工发送)

2、广播接收到后,handler通知异步线程从网上下载数据,是异步(模拟为sleep)

3、数据下载完后handler再通知UI更新



以下是基本的两个代码,可以正确执行

  1. package com.example.testanr;
  2.  
  3. import android.support.v7.app.ActionBarActivity;
  4. import android.content.Intent;
  5. import android.content.IntentFilter;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.view.Menu;
  10. import android.view.MenuItem;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.TextView;
  15.  
  16. public class MainActivity extends ActionBarActivity {
  17. public TextView hellworld = null;
  18. public Button sendBroadcast = null;
  19. public final static String MY_ACTION = "com.example.testanr.MY_ACTION";
  20. public static int i = 0;
  21. public Handler updateUI =new Handler(){
  22.  
  23. @Override
  24. public void handleMessage(Message msg) {
  25. // TODO Auto-generated method stub
  26. super.handleMessage(msg);
  27. if(msg.arg1 ==0){
  28. hellworld.setText("更新UI - "+ i);
  29. i++;
  30. }
  31. }
  32.  
  33. };
  34. public Handler mHandler =new Handler(){
  35.  
  36. @Override
  37. public void handleMessage(Message msg) {
  38. // TODO Auto-generated method stub
  39. super.handleMessage(msg);
  40. if (msg.arg1 == 1 ){
  41. new Thread(new Runnable(){
  42.  
  43. @Override
  44. public void run() {
  45. // TODO Auto-generated method stub
  46. System.out.println("Thread id is "+Thread.currentThread().getId()+",and Thread name is "+Thread.currentThread().getName());
  47. try {
  48. Thread.currentThread().sleep(15000);
  49. } catch (InterruptedException e) {
  50. // TODO Auto-generated catch block
  51. e.printStackTrace();
  52. }
  53.  
  54. Message msg =new Message();
  55. msg.arg1 =0;
  56. updateUI.sendMessage(msg);
  57. }
  58.  
  59. }).start();
  60.  
  61. }
  62. }
  63.  
  64. };
  65. @Override
  66. protected void onCreate(Bundle savedInstanceState) {
  67. super.onCreate(savedInstanceState);
  68. setContentView(R.layout.activity_main);
  69.  
  70. hellworld = (TextView)findViewById(R.id.hello_world);
  71. sendBroadcast = (Button)findViewById(R.id.sendBroadcast);
  72. //生成一个BroadcastReceiver对象
  73. TestReceiver testReceiver = new TestReceiver(mHandler);
  74. //生成一个IntentFilter对象
  75. IntentFilter filter = new IntentFilter();
  76. filter.addAction(MainActivity.MY_ACTION);
  77. //将BroadcastReceiver对象注冊到系统其中
  78. MainActivity.this.registerReceiver(testReceiver, filter);
  79. System.out.println("Thread id is "+Thread.currentThread().getId()+",and Thread name is "+Thread.currentThread().getName());
  80. sendBroadcast.setOnClickListener(new OnClickListener(){
  81.  
  82. @Override
  83. public void onClick(View v) {
  84. // TODO Auto-generated method stub
  85. //发送广播
  86. Intent intent = new Intent();
  87. intent.setAction(MainActivity.MY_ACTION);
  88. sendBroadcast(intent);
  89. }
  90.  
  91. });
  92. }
  93.  
  94. @Override
  95. public boolean onCreateOptionsMenu(Menu menu) {
  96. // Inflate the menu; this adds items to the action bar if it is present.
  97. getMenuInflater().inflate(R.menu.main, menu);
  98. return true;
  99. }
  100.  
  101. @Override
  102. public boolean onOptionsItemSelected(MenuItem item) {
  103. // Handle action bar item clicks here. The action bar will
  104. // automatically handle clicks on the Home/Up button, so long
  105. // as you specify a parent activity in AndroidManifest.xml.
  106. int id = item.getItemId();
  107. if (id == R.id.action_settings) {
  108. return true;
  109. }
  110. return super.onOptionsItemSelected(item);
  111. }
  112. }

还有reciever

  1. package com.example.testanr;
  2.  
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.os.Handler;
  7. import android.os.Message;
  8.  
  9. public class TestReceiver extends BroadcastReceiver {
  10. public Handler handler;
  11. public Message message = null;
  12. public TestReceiver(Handler handler){
  13. this.handler = handler;
  14.  
  15. }
  16.  
  17. @Override
  18. public void onReceive(Context context, Intent intent) {
  19. // TODO Auto-generated method stub
  20. //这里每次都要new,否者会报错
  21. message = new Message();
  22. message.arg1 = 1;
  23. handler.sendMessage(message);
  24. }
  25.  
  26. }

如今才发现一个message是不能往MessageQueue里面发送多次的,否则会报这种错

java.lang.IllegalStateException: The specified message queue synchronization  barrier token has not been posted or has already been removed.

就说这个message的synchronization  barrier
token 已经发送过了的

可是项目里面的问题还没有解决,回头找出原因再发上来

我们知道ANR一般有三种类型

1:KeyDispatchTimeout(5 seconds) --主要类型

按键或触摸事件在特定时间内无响应

2:BroadcastTimeout(10
seconds)

BroadcastReceiver在特定时间内无法处理完毕

3:ServiceTimeout(20 seconds) --小概率类型

Service在特定的时间内无法处理完毕

所以原因还是应该是另外一种,可能没有模拟对

ANR的分析

怎样调查并解决ANR

1:首先分析log

2: 从trace.txt文件查看调用stack.

3: 看代码

4:细致查看ANR的成因(iowait?block?memoryleak?)

可是项目里面log没有输出,是最奇怪的~~~

//************************************9-29更新****************8

回去一看果然是一个message往looper的messagequeue发送了多次!!!可是log没有输出exception,并且为什么会导致ANR,非常奇怪~~~求大神解答

Android 通过广播来异步更新UI的更多相关文章

  1. Android异步更新UI的四种方式

    Android异步更新UI的四种方式 2015-09-06 09:23 segmentfault 字号:T | T 大家都知道由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中 ...

  2. Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

  3. Android异步处理二:使用AsyncTask异步更新UI界面

    在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简 ...

  4. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

  5. Flutter学习笔记(31)--异步更新UI

    如需转载,请注明出处:Flutter学习笔记(31)--异步更新UI 大家都知道,子线程不能操作UI控件,在我们Android的日常开发中,经常会遇到网络请求数据通过线程间通信,将数据发送到UI线程中 ...

  6. 36.Android之多线程和handle更新UI学习

    android经常用到多线程更新UI,今天学习下. 首先布局比较简单: <?xml version="1.0" encoding="utf-8"?> ...

  7. Winform实现多线程异步更新UI(进度及状态信息)

    引言 在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验.所以在大量数 ...

  8. Android中子线程真的不能更新UI吗?

    Android的UI访问是没有加锁的,这样在多个线程访问UI是不安全的.所以Android中规定只能在UI线程中访问UI. 但是有没有极端的情况?使得我们在子线程中访问UI也可以使程序跑起来呢?接下来 ...

  9. 在Android中实现service动态更新UI界面

    之前曾介绍过Android的UI设计与后台线程交互,据Android API的介绍,service一般是在后台运行的,没有界面的.那么如何实现service动态更新UI界面呢?案例:通过service ...

随机推荐

  1. c++,基类声明的指针变量和引用类型变量可以指向派 生类的对象

    基类声明的指针变量和引用类型变量可以指向派生类的对象,而反过来派生类的指针却不能指向基类变量. 这与基类和派生类之间,被允许的赋值方向是相反的. 但是从逻辑上很容易推敲其合理性.

  2. 【转】centos安装memcached+php多服务器共享+session多机共享问题

    参考博文: centos安装memcached 源码安装 Yum安装Memcache Memcached内存分配优化及使用问题 <转>php+memcached 实现session共享 P ...

  3. javascript入门视频第一天 小案例制作 零基础开始学习javascript

    JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此 ...

  4. jquery 单击li防止重复加载的实现代码

    因为加载内容比较慢,所以用户可能在li上不经意点击了两次,那么就会请求两次,这是我们不想看到的. 今天在javascript-jquery群上一筒子发了两个demo给我,他的方法是先将单击的li节点拷 ...

  5. python IDE ulipad配置使用

    一直认为认为python自带的编辑器idle实在是太简陋了,连显示行号的功能都没有,也非常不好编辑.找了下windows平台下的Ide,发现ulipad很多人推荐使用,就开始安装了. 首先去官网: h ...

  6. Jetty:配置概览-须要配置什么

    上一节讲述了怎么配置Jetty,这节将告诉你使用Jetty你须要配置些什么. 配置Server Server实例是Jetty服务端的中心协调对象,它为全部其它Jetty服务端组件提供服务和生命周期管理 ...

  7. A2DP和AVRCP蓝牙音频传输协议的应用解释

    A2DP全名是Advenced Audio Distribution Profile 蓝牙音频传输模型拹定.A2DP 规定了使用蓝牙非同步传输信道方式,传输高质量音乐文件数据的拹议堆栈软件和使用方法, ...

  8. 点击datalist中Button按钮出现“回发或回调参数无效......”

        遇到问题: 回发或回调参数无效.在配置中使用 <pages enableEventValidation="true"/> 或在页面中使用 <%@ Page ...

  9. TOMCAT的域名配置

    链接地址:http://blog.163.com/skk1987@126/blog/static/29303413201051383548377/ 现在很多的公司的网站都是用tomcat作为应用服务区 ...

  10. 高级UIKit-08(TCPSocket)

    [day1001_MoviePlayer]:视频播放 需要导入MediaPlayer.framework - (void)viewDidLoad { [super viewDidLoad]; NSUR ...