I have this Hierarchy in my android app
Activity contains the FragmentGame fragment, that contains the FragmentTypeOfGame;
Activity >> FragmentGame >> FragmentTypeOfGame
Inside FragmentGame, i got a timer and another labels, so, when I change the screen orientation, my game seems restarted, but i can check the timer keeps running (because it`s another thread, I guess).
So my question is, how can I manage to keep all screen running without restarting.
I have already seem these links, but i can't find out how to solve it?
Why not use always android:configChanges="keyboardHidden|orientation"?
Forcing Android to not redraw activity on orientation change
Here goes my manifest:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="orientation"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="@string/app_name" />
<provider android:authorities="com.facebook.app.FacebookContentProviderXXXXXXXXX"
android:name="com.facebook.FacebookContentProvider"
android:exported="true" />
</application>
Here my GameFragment OnCreateView:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Default components start
defaultComponentsStarting(inflater, container);
FourBlocksGameStyle f = new FourBlocksGameStyle();
frgManager.beginTransaction().replace(R.id.rl_root, f, "4blocks").addToBackStack(null).commit();
if (savedInstanceState != null) {
// Restore last state
actualGameTime = savedInstanceState.getDouble("actualGameTime");
}
handler = new Handler(Looper.getMainLooper());
mainRunnable = new Runnable() {
@Override
public void run() {
// Do something and reschedule ourself
if(GAMETIME <= actualGameTime){
cancelTimer();
setLabel(txtTimer, 0, GAMETIME / 1000);
int countSum = Integer.parseInt(txtHits.getText().toString());
//Devolve pra main cuidar da finalização
Intent i = new Intent(ctx, MainActivity.class);
i.putExtra("CountSum", countSum);
startActivity(i);
}
else {
actualGameTime += GAMEDELAY;
double floatingTime = actualGameTime / 1000;
setLabel(txtTimer, 0, floatingTime);
handler.postDelayed(this, GAMEDELAY);
}
}
};
return view;
}
and here my MainActivity onCreate?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
setContentView(R.layout.activity_main);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
final SharedPreferences prefs = getSharedPreferences("hitColor", MODE_PRIVATE);
int startHighscore = prefs.getInt("highScore", 0);
gameOver = new GameOverFragment();
highScoreGameOver = new HighScoreFragment();
game = new GameFragment();
Intent i = getIntent();
int countSum = i.getIntExtra("CountSum", -1);
if(countSum == -1) {
//Log.d("GSS", "Primeira entrada");
if(savedInstanceState == null) {
Log.d("GSS", "savedInstace null");
getFragmentManager()
.beginTransaction()
.replace(R.id.layout_root_view, game)
.addToBackStack(null)
.commit();
}
}
else {
Log.d("GSS", "COUNT: " + String.valueOf(countSum));
Log.d("GSS", "HIGH: " + String.valueOf(startHighscore));
finishGame(countSum, startHighscore, prefs);
}
}
With your current configuration for activity's
configChanges, Your Fragment will recreate the UI when you change the Orientation. Since it will be totally new layout, it makes sense.But your Fragment won't be calling
onCreateagain. It will start fromonCreateViewafter callingonPauseandonStopto destroy the Fragment's UI.So when the Orientation Changes, meaning when the Fragment goes to
onPause, you should save your UI data in aBundleobject (define it as a global variable inside the Fragment) inonPause. Since the Fragment will start fromonCreateViewyou can restore your UI data after inflating your Layout inonCreateViewmethod.Bundle savedInstanceStatewill be null. It won't store your data when the configuration changes, so you cannot rely on that.