Android 通过广播来异步更新UI
来源:互联网 发布:js 复选框控制display 编辑:程序博客网 时间:2024/05/22 08:08
之前的项目里要做一个异步更新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(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);if(msg.arg1 ==0){hellworld.setText("更新UI - "+ i);i++;}}};public Handler mHandler =new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);if (msg.arg1 == 1 ){new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubSystem.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 blocke.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(){@Overridepublic 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;}@Overridepublic 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
- 【Android】Service通过广播更新UI
- 【Android】Service通过广播更新UI
- android异步更新UI
- Service通过广播Broadcast更新Activity UI
- Service通过广播Broadcast更新Activity UI
- Service通过广播Broadcast更新Activity UI
- Service通过广播Broadcast更新Activity UI
- Android 异步更新UI----AsyncTask
- Android 异步更新UI----AsyncTask
- android异步更新UI界面
- Android 异步更新UI----AsyncTask
- android ui异步更新几种分法
- [Android] Service和广播联合更新UI
- android 如何在广播里面更新 UI
- 后台Service通过广播更新UI,Activity通过广播停止Service
- android异步更新UI界面的方法
- android AsyncTask介绍 异步更新UI
- HDU 5029 Relief grain 树链剖分 离线 线段树
- CSDN博文“待审核”检测规则分析之如何避免“待审核”
- 对android中ActionBar中setDisplayHomeAsUpEnabled和setHomeButtonEnabled和setDisplayShowHomeEnabled方法的理解
- Interpolator 的解释
- 基于ultimus平台的项目管理解决方案
- Android 通过广播来异步更新UI
- 快速排序
- Android 动画原理
- vim 去除 ^M
- redhat and centos 系统常用命令
- win7、ubuntu双系统下安全删除ubuntu
- Eclipse——快捷键&Help
- 轻松搞定面试中的链表题目
- 河南教育国际交流学院招生简章