6

向きを変更すると、アプリケーションで奇妙な動作が発生します。

通常の動作:
アプリを開くと、ホーム アクティビティが開始されます。次のアクティビティ (ギャラリー) に移動すると、正常に開始されます (右から左へのスライドイン アニメーション)。戻るキーを使用して戻ると、現在のアクティビティ (ギャラリー) が終了します (左から右へのスライド アウト アニメーション)。

奇妙な振る舞い:

  • アプリを縦向きモードで起動し、向きを横向きに変更すると。次に、ホーム アクティビティの 2 回目のインスタンスのようなものがあります。ランドスケープモードで戻るボタンを押しても、向きを変更しない場合のようにアプリを閉じないため (ホームアクティビティは私のアプリの最初のアクティビティです)、左から右にスライドするアニメーションを作成します (新しいアクティビティを開始するなど)。ホーム アクティビティ (ただし、別のインスタンスだと思います) を再度表示します。戻るボタンをもう一度押すと、アプリが閉じます。
  • アプリを横向きモードで起動し、向きを縦向きモードに変更すると、[戻る] ボタンを押すと、右から左へのスライド アニメーションが表示され (アクティビティを閉じるように)、ホーム アクティビティが再び表示されます。
  • アプリを起動し、縦、横、縦の 2 つの向きを変更すると、戻るボタンでアプリが閉じます。

つまり、ランドスケープ モードとポートレート モードは 2 つの異なるアクティビティのように扱われます。

私は を使用しないandroid:configChanges="orientation|keyboardHidden|screenSize"ので、向きの変更は通常の Android アクティビティのライフサイクルに従い、「古い」ポートレート (またはランドスケープ) バージョンのアクティビティを破棄する必要があります。
私のアクティビティは から継承してFragmentActivityいます。私はonSaveInstanceStateparceable (アクティビティへの参照を含まない) を渡すために使用しており、onRetainCustomNonConfigurationInstance( read here ) を使用して複数AsyncTaskの s を渡しています。ただし、これらのタスクのすべての参照 (存在する場合) は で破棄されonRetainCustomNonConfigurationInstance、後で (新しく作成されたアクティビティで) 復元されgetLastCustomNonConfigurationInstanceます。

この動作を引き起こす可能性のあるアイデアはありますか?

編集:
マニフェスト ファイルのアクティビティ宣言:
<activity android:name=".activities.smartphone.HomeSmartphone" android:label="@string/app_name"></activity>

HomeSmartphone は Home を
拡張します Home は MyFragmentActivityを拡張します
MyFragmentActivity は android.support.v4.app.FragmentActivity を拡張 します

MyFragmentActivity では、onCreate、onRestart、onStart、onSaveInstanceState、onPause、onResume、onStop、onDestroy で、アプリケーション コンテキストへの参照を保持するだけの追跡クラスの静的メソッドを呼び出して、いくつかのログ記録/追跡を行います。アクティビティのコンテキストではありません。

Home は、HomeSmartphone と HomeTablet によって拡張される抽象クラスです。これら 2 つのクラスは、異なるレイアウトで特別な読み込み/更新/初期化を行います。

ほとんどのタスクは、抽象 Home クラスで実行されます。



    public HomeRetainedObjects retained = new HomeRetainedObjects();

    public boolean adIsShown = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.home);

        Log.i("DEBUG", "onCreate(Home)");

        if (savedInstanceState != null) {
            this.adIsShown = savedInstanceState.getBoolean("adIsShown");
        }

    // write/update values in shared preferences
        this.initPreferences();

    // recover retained objects (mostly AsyncTasks)
        this.recoverRetained();

    // show content / refresh content
        this.init();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putBoolean("adIsShown", this.adIsShown);

        Log.i("DEBUG", "onSaveInstanceState(Home)");
    }

    public void recoverRetained() {
        Object retained = this.getLastCustomNonConfigurationInstance();
        if (retained instanceof HomeRetainedObjects) {
            this.retained = (HomeRetainedObjects) retained;

            if (this.retained.loadMessageTask != null) {
                this.retained.loadMessageTask.restoreContext(this);
            }
        }
    }

    @Override
    public Object onRetainCustomNonConfigurationInstance() {
        if (this.retained.loadMessageTask != null) {
            this.retained.loadMessageTask.destroyContext();
        }

        return this.retained;
    }

これが役に立てば幸いです?!

4

1 に答える 1

0

同様の問題に遭遇しましたが、問題の原因はオーバーライドしているようonRetainCustomNonConfigurationInstance()です。

保持状態オブジェクトを確認したところ、. への参照が保持されていることがわかりましたContext。でラップするWeakReferenceと、通常の動作が返され、奇妙な二重インスタンスは残りませんでした。

おそらく、保持状態もContext?への参照を保持しています。

于 2012-08-31T19:38:40.777 に答える