Bug : Theme.Translucent & FLAG_ACTIVITY_REORDER_TO_FRONT

时间秒杀一切 提交于 2019-12-04 16:12:24

问题


I have an activity with the translucent Theme :

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

Also the problem is reproduceable with just this Theme:

<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>

This activity is loaded at startup and kept in memory (when I start this activity, I ad the FLAG_ACTIVITY_REORDER_TO_FRONT flag as extra).

Problem : when I start this activity (from the menu), the activity don't show up, nothing happens. But : if I remove the translucent theme : all works fine, the activity is back to front.

Yes onNewIntent() is called.

And if I press back the translucent activity is the one below! But it needs to be the top.

An example being

A ( translucent activity) B C

Stack: A

A startActivity(B)

Stack: A,B

B startActivity(C)

Stack: A,B,C

c startActivity(A) // with flag FLAG_ACTIVITY_REORDER_TO_FRONT

Stack should be: B,C,A

but A is never brought to the front, although its onNewIntent() is called.

Any ideas?

Side notes


Interesting unanswered question: http://groups.google.com/group/android-developers/browse_thread/thread/269c67f6b39cfe45?pli=1


android:launchMode of singleTask or singleInstance are not wanted to be used. These change the backstack and move activities into their own stack. Therefore we don't have A,B,C any more.

singleTask and singleInstance — are not appropriate for most applications, since they result in an interaction model that is likely to be unfamiliar to users and is very different from most other applications.

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

Anyone who wants a visual representation of launchModes try this app : https://play.google.com/store/apps/details?id=com.novoda.demos.activitylaunchmode


回答1:


If we do not set the theme from AndroidManifest.xml, activity block and set the theme before setContentView, in onCreate method in the first translucent activity, the problem is solved, below is the code:

public class TranslucentActivityDemoActivity extends Activity {

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

    }



回答2:


As a workaround not an answer

I have done this:

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

if anyone can give me an answer they win the brucey bonus!




回答3:


The launchMode should be singleTask in the <activity> tag of your activity in the manifest file.

From Documentation :

singleTask - If, when starting the activity, there is already a task running that starts with this activity, then instead of starting a new instance the current task is brought to the front. The existing instance will receive a call to Activity.onNewIntent() with the new Intent that is being started, and with the Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT flag set. This is a superset of the singleTop mode, where if there is already an instance of the activity being started at the top of the stack, it will receive the Intent as described there (without the FLAG_ACTIVITY_BROUGHT_TO_FRONT flag set).

Update

As a better workaround you can try invalidating the whole window in onNewIntent() or in onResume..

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



回答4:


I just removed the FLAG and it's all working for me,There is no any problem..First Activity Remain Transparent and getting on top when called..Just Try.

Here the code of my whole example,

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

Edit Activity with 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:


Here's my workaround idea. I believe the problem is triggered by requesting a translucent activity in the backstack to be brought to the front. Since we cannot do that, let's just start a new copy of the translucent activity, but instead of completely recreating one from scratch, let's reduce the amount of work by utilizing a fragment.

So if your translucent activity looked like this (copied from MKJParekh's answer):

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

We can convert it to something like this:

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

With this code, we don't need to use the FLAG_ACTIVITY_REORDER_TO_FRONT flag when starting FirstAct later since it will in the background use the SavedState from its previous copy as the initial state of the new copy.

Please note that in my sample code above I simply destroyed the old copy of FirstAct (by calling finish() after saving the fragment instance state) in its onPause(). A more serious implementation would probably set a flag instead (to be checked in onResume()) whether a particular copy need to be finish()ed when revisited in the stack (if it has been "brought to front" as a newer copy).




回答6:


I had this same problem. I moved the uses-permission tag before the application tag in AndroidManifest.xml. That fixed it for me.



来源:https://stackoverflow.com/questions/9309479/bug-theme-translucent-flag-activity-reorder-to-front

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!