Ошибка: Theme.Translucent & FLAG_ACTIVITY_REORDER_TO_FRONT - программирование
Подтвердить что ты не робот

Ошибка: Theme.Translucent & FLAG_ACTIVITY_REORDER_TO_FRONT

У меня есть активность с полупрозрачной темой:

android:theme="@android:style/Theme.Translucent.NoTitleBar"

Также проблема воспроизводится только с помощью этой темы:

<style name="MyTheme" parent="@android:style/Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:colorBackground">@null</item>
</style>

Эта операция загружается при запуске и сохраняется в памяти (когда я запускаю эту операцию, я добавляю флаг FLAG_ACTIVITY_REORDER_TO_FRONT как дополнительный).

Проблема: когда я запускаю это действие (из меню), активность не отображается, ничего не происходит. Но: если я удаляю полупрозрачную тему: все работает нормально, активность возвращается на передний план.

Да onNewIntent() вызывается.

И если я вернусь, полупрозрачная активность будет ниже! Но он должен быть вершиной.

Примером является

A (полупрозрачная активность) B C

Стек: A

A startActivity (B)

Стек: A, B

B startActivity (C)

Стек: A, B, C

c startActivity (A)//с флагом FLAG_ACTIVITY_REORDER_TO_FRONT

Стек должен быть: B, C, A

но A никогда не выводится на передний план, хотя вызывается его onNewIntent().

Любые идеи?

Боковые заметки


Интересный безответный вопрос: http://groups.google.com/group/android-developers/browse_thread/thread/269c67f6b39cfe45?pli=1


android:launchMode из singleTask или singleInstance не нужны. Они изменяют заднюю часть и перемещают действия в их собственный стек. Поэтому мы больше не имеем A, B, C.

singleTask и singleInstance - не подходят для большинства приложений, поскольку они приводят к модели взаимодействия, которая, вероятно, быть незнакомым пользователям и сильно отличается от большинства других приложения.

http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

Любой, кто хочет визуальное представление launchModes, попробует это приложение: https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode

4b9b3361

Ответ 1

Если мы не задаем тему из AndroidManifest.xml, блок активности и задаем тему перед setContentView, в методе onCreate в первом полупрозрачном действии проблема решена, ниже приведен код:

public class TranslucentActivityDemoActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      this.setTheme(R.style.myTheme);
        setContentView(R.layout.main);

    }

Ответ 2

launchMode должен быть singleTask в теге <activity> вашей активности в файле манифеста.

Из документации:

singleTask - Если при запуске операции уже есть задача который начинается с этого действия, затем вместо запуска нового Например, текущая задача доведена до фронта. Существующий экземпляр получит вызов Activity.onNewIntent() с новым Запуск, который начинается, и с Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT установлен флаг. Это надмножество режим singleTop, где, если уже есть экземпляр активность начинается в верхней части стека, она будет получать Намерение, описанное здесь (без FLAG_ACTIVITY_BROUGHT_TO_FRONTфлаг).

Update

В качестве лучшего обходного пути вы можете попробовать сделать недействительным все окно в onNewIntent() или в onResume..

@Override
protected void onNewIntent(Intent intent) {
   super.onNewIntent(intent);
   getWindow().getDecorView().invalidate();
}

Ответ 3

Как обход не ответ

Я сделал это:

public class OverlayActivity extends Activity {

   @Override
   protected void onNewIntent(Intent intent) {
       super.onNewIntent(intent);
       // Restart self when attempting to be brought to front
       Intent restartIntent = new Intent(this, OverlayActivity.class);
       startActivity(restartIntent);
       finish();
   }

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_overlay);
   }
 }

если кто-нибудь может дать мне ответ, он выиграет бонус brucey!

Ответ 4

Я просто удалил FLAG, и все это работало для меня. Нет никаких проблем. Первая работа остается прозрачной и набирается сверху при вызове. Просто попробуйте.

Вот код моего всего примера,

FirstAct

public class FirstAct extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       Button btn = new Button(this);
       btn.setText("First Here Go To Second");
       btn.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            Intent intent = new Intent(FirstAct.this,SecondAct.class);
            startActivity(intent);
        }
    });
       setContentView(btn);
    }
}

SecondAct

public class SecondAct extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       Button btn = new Button(this);
       btn.setText("Second Here Go To Third");
       btn.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            Intent intent = new Intent(SecondAct.this,ThirdAct.class);
            startActivity(intent);
        }
    });
       setContentView(btn);
    }
}

ThirdAct

public class ThirdAct extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       Button btn = new Button(this);
       btn.setText("Third Here Go To First");
       btn.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            Intent intent = new Intent(ThirdAct.this,FirstAct.class);
            //intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            startActivity(intent);
        }
    });
       setContentView(btn);
    }
}

Изменить действие с помощью LaunchMode SingleInsance * Manifest *

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.mj.temp"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".FirstAct" android:theme="@android:style/Theme.Translucent.NoTitleBar"  android:launchMode="singleInstance"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="SecondAct" android:launchMode="singleInstance"></activity>
        <activity android:name="ThirdAct" android:launchMode="singleInstance"></activity>
    </application>
</manifest>

Ответ 5

Вот моя обходная идея. Я считаю, что проблема вызвана запросом полупрозрачной активности в задней стопке, которая будет перенесена на фронт. Поскольку мы не можем этого сделать, давайте просто запустим новую копию полупрозрачной активности, но вместо полного воссоздания одного с нуля позволим сократить объем работы за счет использования фрагмента.

Итак, если ваша полупрозрачная активность выглядела так (скопирована из ответа MKJParekh):

public class FirstAct extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button btn = new Button(this);
        btn.setText("First Here Go To Second");
        btn.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                Intent intent = new Intent(FirstAct.this, SecondAct.class);
                startActivity(intent);
            }
        });
        setContentView(btn);
    }
}

Мы можем преобразовать его в следующее:

public class FirstAct extends FragmentActivity {
    private static SavedState mSavedState;
    private FirstFrag mFrag;

    public static class FirstFrag extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            final Context context = inflater.getContext();
            Button btn = new Button(context);
            btn.setText("First Here Go To Second");
            btn.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    Intent intent = new Intent(context, SecondAct.class);
                    startActivity(intent);
                }
            });
            return btn;
        }    
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);    
        mFrag = new FirstFrag();
        if (mSavedState != null) mFrag.setInitialSavedState(mSavedState);
        getSupportFragmentManager()
            .beginTransaction()
            .add(android.R.id.content, mFrag)
            .commit();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mSavedState = getSupportFragmentManager().saveFragmentInstanceState(mFrag);
        finish();
    }    
}

С этим кодом нам не нужно использовать флаг FLAG_ACTIVITY_REORDER_TO_FRONT при запуске FirstAct позже, так как в фоновом режиме используйте SavedState из его предыдущей копии в качестве исходного состояния новой копии.

Обратите внимание, что в моем примере кода я просто уничтожил старую копию FirstAct (вызывая finish() после сохранения состояния экземпляра фрагмента) в onPause(). Более серьезная реализация, вероятно, установила бы флаг (для проверки в onResume()), должна ли конкретная копия быть finish() изменена при повторном просмотре в стеке (если она была "перенесена вперед" в качестве более новой копии).

Ответ 6

У меня была такая же проблема. Я переместил тег использования-разрешения перед тегом приложения в AndroidManifest.xml. Это исправило это для меня.