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

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

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

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

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



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

package com.example.testanr;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends ActionBarActivity {
public TextView hellworld = null;
public Button sendBroadcast = null;
public final static String MY_ACTION = "com.example.testanr.MY_ACTION";
public static int i = 0;
public Handler updateUI =new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if(msg.arg1 ==0){
hellworld.setText("更新UI - "+ i);
i++;
}
} };
public Handler mHandler =new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if (msg.arg1 == 1 ){
new Thread(new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread id is "+Thread.currentThread().getId()+",and Thread name is "+Thread.currentThread().getName());
try {
Thread.currentThread().sleep(15000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} Message msg =new Message();
msg.arg1 =0;
updateUI.sendMessage(msg);
} }).start(); }
} };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); hellworld = (TextView)findViewById(R.id.hello_world);
sendBroadcast = (Button)findViewById(R.id.sendBroadcast);
//生成一个BroadcastReceiver对象
TestReceiver testReceiver = new TestReceiver(mHandler);
//生成一个IntentFilter对象
IntentFilter filter = new IntentFilter();
filter.addAction(MainActivity.MY_ACTION);
//将BroadcastReceiver对象注冊到系统其中
MainActivity.this.registerReceiver(testReceiver, filter);
System.out.println("Thread id is "+Thread.currentThread().getId()+",and Thread name is "+Thread.currentThread().getName());
sendBroadcast.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View v) {
// TODO Auto-generated method stub
//发送广播
Intent intent = new Intent();
intent.setAction(MainActivity.MY_ACTION);
sendBroadcast(intent);
} });
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

还有reciever

package com.example.testanr;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message; public class TestReceiver extends BroadcastReceiver {
public Handler handler;
public Message message = null;
public TestReceiver(Handler handler){
this.handler = handler; } @Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
//这里每次都要new,否者会报错
message = new Message();
message.arg1 = 1;
handler.sendMessage(message);
} }

如今才发现一个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. iOS 把图片从Mac本地添加到iOS Simulator中

    [把图片从Mac本地添加到iOS Simulator中] 1. 把图片从Mac本机拖动到iOS Simulator中: 2. iOS Simulator会自动打开Safari去打开对应的图片,然后你用 ...

  2. gcc支持c99验证

    gcc3.0以上的版本都是支持C99标准的, 但是编译程序的时候需要加上    -std=c9  才可以: 一下程序是验证gcc是否支持c99标准的: #include <stdio.h> ...

  3. C++拾遗

    1三个概念 字符串字面值是一串常量字符(是一个常量),字符串字面值常量用双引号括起来的零个或多个字符表示,为兼容C语言,C++中所有的字符串字面值都由编译器自动在末尾添加一个空字符.字符串字面值的类型 ...

  4. vim的漫漫长征路

    在系统的学习vim之前,先在网上找了些教程大概了解下,因为首先我们要先将vim给用起来,然后在系统的学习过程中不断的充实自己对vim的理解. ----------------------------- ...

  5. 金融管理 - MBA智库百科

    金融管理 - MBA智库百科     金融管理    出自 MBA智库百科(http://wiki.mbalib.com/)     金融管理(Financial Management)    目录  ...

  6. 解决struts2中UI标签出现的问题: The Struts dispatcher cannot be found

    解决struts2中UI标签出现的问题: The Struts dispatcher cannot be found 异常信息: The Struts dispatcher cannot be fou ...

  7. JAVA思维导图系列:多线程0基础

    感觉自己JAVA基础太差了,又一次看一遍,已思维导图的方式记录下来 多线程0基础 进程 独立性 拥有独立资源 独立的地址 无授权其它进程无法訪问 动态性 与程序的差别是:进程是动态的指令集合,而程序是 ...

  8. C++ 中dynamic_cast&lt;&gt;的用法

    /*这是从网上摘下的样例,主要讲述了 dynamic_cast<> 的用法.*/ /* 作用:将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会依据基类指针是否真 ...

  9. Cocos Studio和Cocos2d-x版本对应关系

    链接地址:http://www.cocoachina.com/bbs/read.php?tid=182077 可以在cocos2d.cpp中查看2d-x的版本信息.   版本对应列表: Studio2 ...

  10. 工作随记 warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds

    错误信息:F:\BUILD\IDS7020\trunk\manage_src\dev\java_src\tds7030-web\Ant\build.xml:344: warning: 'include ...