ユーザーがANRに遭遇しないようにする


  • ANR概要
  • Androidは以下のcaseを処理するために専用のThreadを持っている:1)ユーザ入力に所定時間応答していない(例えば、ボタン、タッチスクリーン)2)BroadcastReceiverが所定時間内に実行されていない場合、システムはユーザにダイアログボックスを表示し、このダイアログボックスは、アプリケーション応答なし(ANR:Application NotResponding)ダイアログボックスと呼ばれます.
  • ANR
  • 回避
    ANRを引き起こす本質的な原因は,メイン(main)Threadが多忙でユーザ入力を処理できないことである.ANRを避けるにはmain threadをブロックするものをサブスレッドに移植する必要がある(以下、ANRを引き起こすコードと最適化されたコード).
    
    //cause ANR
     public void onUpdate(int itemPos,  final String itemName, UpdateInfo update) {
    	             final String[] fields = new String[5];
    	             fields[0] = notifyValue(update, X1);
    	             fields[1] = notifyValue(update, X2);
    	             fields[2] = notifyValue(update, X3);
    	             fields[3] = notifyValue(update, X4);
    	             fields[4] = notifyValue(update, X5);
    	             
                    Message msg =  messageHandler.obtainMessage(); 
                    msg.what = MESSAGE_HANDLE_ID_UPDATEROW_DATA;
    				Bundle bundle = new Bundle();
    				bundle.putInt(MESSAGE_KEY_ID, Integer.parseInt(itemName, 10));
    				bundle.putString(X1,  fields[0] );
    				bundle.putString(X2, fields[1]);
    				bundle.putString(X3, fields[2]);
    				bundle.putString(X4, fields[3]);
    				bundle.putString(X5, fields[4]);
    				msg.setData(bundle);
    				messageHandler.sendMessage(msg);
    }
    
    
    private  Handler messageHandler = new Handler() {
    
    		@Override
    		public void handleMessage(Message msg) {
    			
    		switch(msg.what) {
    			case  MESSAGE_HANDLE_ID_UPDATEROW_DATA:{
    			  int id = msg.getData().getInt(MESSAGE_KEY_ID);
    				String fields[] = new String[5];
    				fields[0] = msg.getData().getString(X1);
    				fields[1] = msg.getData().getString(X2);
    				fields[2] = msg.getData().getString(X3);
    				fields[3] = msg.getData().getString(X4);
    				fields[4] = msg.getData().getString(X5);
    				updateRowInTable(id, fields);
    				break;
    			}
    }
    
    // high performance
     public void onUpdate(int itemPos,  final String itemName, UpdateInfo update) {
    	             final String[] fields = new String[5];
    	             fields[0] = notifyValue(update, X1);
    	             fields[1] = notifyValue(update, X2);
    	             fields[2] = notifyValue(update, X3);
    	             fields[3] = notifyValue(update, X4);
    	             fields[4] = notifyValue(update, X5);
    
    			final Runnable myUpdateResults = new Runnable() {
    			        public void run() {
    			        	updateRowInTable(Integer.parseInt(itemName, 10), fields);
    			        }
    			    };
    			    
    			     new Thread() {
    		            public void run() {
    		            	messageHandler.post(myUpdateResults);
    		            }
    		        }.start();
    
     private  Handler messageHandler = new Handler();