问题
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 theIntent.FLAG_ACTIVITY_BROUGHT_TO_FRONTflag 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 theFLAG_ACTIVITY_BROUGHT_TO_FRONTflag 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