Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 通過廣播來異步更新UI

Android 通過廣播來異步更新UI

編輯:關於Android編程

之前的項目裡要做一個異步更新UI的功能,但是結果出現了ANR,所以想寫個demo來測試到底是哪個地方出現了問題,結果發現原來的思路是沒有問題,郁悶\~~

現在這個demo 就是模擬項目裡面 的步驟<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PHN0cm9uZz4xoaK908rVtb3Ptc2ztcS547Klo6jP1tTaxKPE4s6qyMu5pLeiy82jqTwvc3Ryb25nPjwvcD4KPHA+PHN0cm9uZz4yoaK547KlvdPK1bW9uvOjrGhhbmRsZXLNqNaq0uyyvc/fs8y00834yc/PwtTYyv2+3aOsysfS7LK9o6jEo8TizqpzbGVlcKOpPC9zdHJvbmc+PC9wPgo8cD48c3Ryb25nPjOhosr9vt3PwtTYzeq682hhbmRsZXLU2c2o1qpVSbj80MI8L3N0cm9uZz48L3A+CjxwPjxzdHJvbmc+PGJyPgo8L3N0cm9uZz48L3A+CjxwPjxzdHJvbmc+z8LD5srH1vfSqrXEwb249rT6wuujrMTcubvV/ci31MvQ0Dwvc3Ryb25nPjwvcD4KPHA+PGJyPgo8L3A+CjxwPjxwcmUgY2xhc3M9"brush:java;">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沒有輸出,是最奇怪的~~~


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved