Huawei だけで何故か startActivity するときに渡したデータが消失してクラッシュすることがあったので調査した。
結果
ソースコードとかあってゴチャゴチャするので先に結果を書いてしまう。
- 恐らく Huawei の Android 5.0〜6.0.1 の端末のみで発生するバグ。7, 8系とかでは発生しない。
- 発生条件は startActivity() するときに渡す Bundle データに Serializable なオブジェクトを渡すこと。
- アクティビティが破棄されたあとに復帰しようとしたタイミングで発生する。
再現方法
コードについて
- MainActivity は固定値 "first_value" という String を渡して startActivity しているだけ
- SecondActivity ではその String を取得して TextView に設定しているだけ。
実際に試す
- 実行前に "開発者向けオプション" から "アクティビティを保持しない" にチェックしておく
- 実行して起動すると "first_value"という文字列が表示される
- アプリをバックグランドに送る
- アプリをタスクから選択して復帰する。すると Bundle に入れておいた "first_value"がnullになっているので、何も TextView に表示されない
package net.test;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import net.test.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
startActivity(SecondActivity.createIntent(this, "first_value"));
}
}
package net.test;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import net.test.databinding.ActivitySecondBinding;
import java.io.Serializable;
public class SecondActivity extends AppCompatActivity {
public static final String BUNDLE_KEY_FIRST = "BUNDLE_KEY_FIRST";
public static final String BUNDLE_KEY_SECOND = "BUNDLE_KEY_SECOND";
public static class MyObject implements Serializable {
}
public static Intent createIntent(Context context, String value) {
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra(BUNDLE_KEY_FIRST, value);
intent.putExtra(BUNDLE_KEY_SECOND, new MyObject()); // この行があると問題が起きる
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivitySecondBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_second);
String firstValue = getIntent().getStringExtra(BUNDLE_KEY_FIRST); // これが null になる
binding.firstValueTextview.setText(firstValue);
}
}
ポイント
- この行があると問題が起きると書いてあるところをコメントアウトすると問題は発生しない
- Serializable なデータが一つでも Bundle に入っていると他のデータも含めて全部消される
同じ問題でも若干のバラツキがあったり
- HUAWEI MediaPad M3 (BTV-DL09) では必ず再現する
- MediaPad T2 (FDR-A01w) では2回に1回ぐらい再現する
対処方法
- わからん。。
- データを設定して Acitivty を起動している全箇所で getIntent().getExtras() != null とかするのか・・?