お世話になっております。いつも質問や回答を拝見して勉強させて頂いております。
早速ですが、端末回転時の処理について質問させてください。
現象:
端末の回転が有効になっている状態の時に、高速で端末を縦/横繰り返すとクラッシュエラーが発生する
クラッシュ内容は NullPointerException でした。
処理内容:
@Override
public void onCreate(Bundle savedInstanceState) {
:
: 略
:
// MapViewのオーバーレイ作成
locationOverlay=new LocationOverlay(
getResources().getDrawable(R.drawable.location_icon),map);
map.getOverlays().add(locationOverlay);
:
// センサーの初期化
mSensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
:
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// 現在のマーカー位置の保存等(特に現象に関する処理は無い)
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// 現在のマーカー位置の復帰等(特に現象に関する処理は無い)
}
@Override
protected void onResume() {
super.onResume();
map.requestLayout();
if(mSensorManager!=null){
List<Sensor> sensors=mSensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if(sensors.size()>0){
Sensor sensor = sensors.get(0);
mRegisteredSensor=mSensorManager.registerListener(
this,sensor,SensorManager.SENSOR_DELAY_NORMAL);
}
}
:略
}
@Override
protected void onPause() {
super.onPause();
if(mRegisteredSensor){
mSensorManager.unregisterListener(this);
mRegisteredSensor = false;
}
:略
}
@Override
protected void onDestroy(){
:略
map.getOverlays().remove(locationOverlay);
locationOverlay.clear();
locationOverlay=null;
mSensorManager=null;
}
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ORIENTATION){
locationOverlay.SetAngle(event.values[0]);
map.invalidate();
}
}
public void onLocationChanged(Location location) {
locationOverlay.SetLocation(location);
map.invalidate();
}
通常の端末回転時のシーケンスは
開始
onSaveInstanceState
onPause
onDestroy
復帰
onCreate
onRestoreInstanceState
onResume
だと認識していますし、ブレークポイントを置いて確認してもこの通りでした。
ブレークポイントを置いた状態で端末を回転させても現象は発生しませんでした。
ブレークポイントを置かずに表示が回転した事を確認してから縦/横を続けても発生しませんが
表示を無視して縦/横回転をササっと続けると1分もせずに強制終了し
locationOverlay が null の状態で onSensorChanged や onLocationChanged が発生します。
念のためlocationOverlayをnullにしている所を検索してみましたが
onDestroy以外には無い為、処理が追いつかず onSensorChanged 等の
イベントが溜り onDestroy と onCreate の間に届いているのではと考えます。
対策として locationOverlay をアクセスする所に
if(locationOverlay!=null) を入れるとエラーが発生しなくなった様に見えていますし
onDestroyの locationOverlay=null; の行を削除しても現象は発生しないようです。
あまりにも長くなるので略しましたが
実は、LocationListner は Services で動いていて Messenger を使って
Activity と通信しています。
この回転を続けた時の現象はlocationOverlayだけではなく
Messenger のハンドラーでも発生しています。
Messenger も同様にonPauseで通信を停止し onDestroy でnullにしています。
既に公開済のアプリでエラー報告は届いていませんが
気付いてしまったからには、何か対策したいと考えています
綺麗な対策方法がみつかりませんので
良い対策方法等ありましたら御教授頂きたいと思い質問させて頂きました。
余談になりますが、他のアプリはどうなのかなっと
Marketからダウンロードして使わせて頂いているアプリで同じ事をしてみると
クラッシュするアプリも有りました。
そんな事をする人が悪い! そんな事をする人は居ない!
っと自分に言い聞かせてみましたが気になって離れられません。
何かお気付きの事が有りましたら、よろしくお願いします。