Ошибка: тема.Прозрачный & FLAG_ACTIVITY_REORDER_TO_FRONT - PullRequest
17 голосов
/ 16 февраля 2012

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

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 не требуется использовать. Они изменяют backstack и перемещают действия в свой собственный стек. Поэтому у нас больше нет 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

Ответы [ 6 ]

1 голос
/ 30 апреля 2012

Если мы не устанавливаем тему из 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);

    }
0 голосов
/ 10 ноября 2013

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

0 голосов
/ 28 марта 2013

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

Так что если ваша полупрозрачная активность выглядела какэто (скопировано из ответа 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() редактировать конкретную копию при повторном рассмотрении в стеке (если она была «перенесена на передний план» как более новая копия).

0 голосов
/ 28 апреля 2012

Я просто удалил ФЛАГ, и все это работает для меня, нет никаких проблем .. Первая активность остается прозрачной и становится на вершине при вызове .. Просто попробуйте.

Здеськод всего моего примера:

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 * Манифест *

<?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>
0 голосов
/ 24 апреля 2012

В качестве обходного пути не ответ

Я сделал это:

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);
   }
 }

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

0 голосов
/ 23 апреля 2012

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

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

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

Обновление

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

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