在Android上重新启动活动
在我的Android应用程序中,当我旋转设备(滑出键盘)时,我的在Android上重新启动活动,android,rotation,android-activity,Android,Rotation,Android Activity,在我的Android应用程序中,当我旋转设备(滑出键盘)时,我的活动将重新启动(onCreate)。现在,这可能是应该的,但我在onCreate方法中进行了很多初始设置,因此我需要: 将所有初始设置放在另一个功能中,这样就不会在设备旋转或 使创建时不再调用onCreate,布局只是调整或更改 将应用程序限制为仅纵向,以便不调用onCreate 您描述的是默认行为。您必须通过添加以下内容来检测和处理这些事件: android:configChanges 添加到清单,然后添加要处理的更改。因此,对
活动将重新启动(onCreate
)。现在,这可能是应该的,但我在onCreate
方法中进行了很多初始设置,因此我需要:
将所有初始设置放在另一个功能中,这样就不会在设备旋转或
使创建时不再调用onCreate
,布局只是调整或更改
将应用程序限制为仅纵向,以便不调用onCreate
您描述的是默认行为。您必须通过添加以下内容来检测和处理这些事件:
android:configChanges
添加到清单,然后添加要处理的更改。因此,对于方向,您将使用:
android:configChanges="orientation"
android:configChanges="keyboardHidden"
对于要打开或关闭的键盘,您将使用:
android:configChanges="orientation"
android:configChanges="keyboardHidden"
如果要处理这两个问题,可以使用管道命令将它们分开,如:
android:configChanges="keyboardHidden|orientation"
这将在您调用的任何活动中触发onConfigurationChanged方法。如果重写该方法,则可以传入新值
希望这有帮助。使用应用程序类
根据您在初始化过程中所做的,您可以考虑创建一个新的类,该类扩展了<代码>应用程序>代码>,并将初始化代码移动到该类中重写的<代码> OnCudio< /Cult>方法。
public class MyApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
// TODO Put your application initialization code here.
}
}
application类中的onCreate
仅在创建整个应用程序时才被调用,因此活动在方向或键盘可见性更改时重新启动不会触发它
将这个类的实例作为一个单例公开,并使用getter和setter公开正在初始化的应用程序变量,这是一个很好的实践
注意:您需要在清单中指定要注册和使用的新应用程序类的名称:
或:
即使更改android的方向
,仍然会调用onCreate
方法。因此,将所有繁重的功能移到这种方法上并不会对您有所帮助我刚刚发现了以下知识:
通过方向更改使活动保持活动状态,并通过onConfigurationChanged
处理活动,并在清单文件中建议:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
android:screenOrientation="portrait"
它还有一个额外的好处,就是它总是有效的
另外,省略键盘隐藏
似乎合乎逻辑,但它会导致仿真器出现故障(至少对于Android 2.1而言):仅指定方向
将使仿真器调用OnCreate
和onConfiguration有时会更改
,有时只调用OnCreate
我没有在设备上看到失败,但我听说其他设备的仿真器失败了。所以值得记录。我所做的
在清单的“活动”部分中,添加了:
android:configChanges="keyboardHidden|orientation"
在活动的代码中,实现了:
//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
//get views from ID's
this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);
//etc... hook up click listeners, whatever you need from the Views
}
//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
InitializeUI();
}
//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
InitializeUI();
}
您还可以考虑使用Android平台的跨方向性数据持久化的方式:<代码> OnReNeNealDebug()/<代码>和<代码> GETLASTNONFUTCONTION STANSACTIONS()/<代码>
这允许您跨配置更改保存数据,例如您可能从服务器获取的信息或在
onCreate
中或之后计算的其他信息,同时还允许Android使用xml文件重新布局您的活动
看到或看到
应该注意的是,这些方法现在已被弃用(尽管仍然比上述大多数解决方案所建议的自己处理方向更改更灵活),建议每个人都切换到Fragments
,而改用setRetainInstance(true)
在您要保留的每个片段上。要在Android清单中进行的更改包括:
android:configChanges="keyboardHidden|orientation"
活动中要添加的内容包括:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
清单的哪个部分告诉它“不要调用onCreate()
”
而且,
谷歌的文档说要避免使用android:configChanges
(除非作为最后手段)。。。。但是他们建议的替代方法都使用了android:configChanges
根据我的经验,模拟器在旋转时总是调用onCreate()
。
但是我运行相同代码的1-2台设备。。。不要。
(不确定为什么会有任何不同。)Android 3.2及更高版本的更新:
注意:从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,“屏幕大小”也会改变。因此,如果要防止在为API级别13或更高版本开发时由于方向更改而重新启动运行时(如minSdkVersion和targetSdkVersion属性所声明的),则必须在的“方向”
值之外添加的“屏幕大小”
值。也就是说,您必须声明android:configChanges=“orientation | screenSize”
。但是,如果您的应用程序的目标API级别为12或更低,则您的活动始终会自行处理此配置更改(此配置更改不会重新启动您的活动,即使在Android 3.2或更高版本的设备上运行时也是如此)
尽管这不是“Android方式”,但我自己处理方向的变化,并简单地在视图中重新定位小部件,以将改变的方向考虑在内,从而获得了非常好的结果。这比任何其他方法都要快,因为不必保存和恢复视图。它还为用户提供了更无缝的体验,因为重新定位的小部件是完全相同的小部件,只是移动和/或调整了大小。这样不仅可以保存模型状态,还可以保存视图状态
RelativeLayout
有时是一个很好的选择
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
onConfigurationChanged is called when the screen rotates.
(onCreate is no longer called when screen rotates due to manifest, see:
android:configChanges)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_list);
if(savedInstanceState == null){
setupCloudMessaging();
}
}
android:configChanges="keyboard|keyboardHidden|orientation"
android:configChanges="orientation"
android:configChanges="orientation"
android:configChanges="keyboardHidden|orientation|screenSize"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
android:configChanges="screenLayout|screenSize|orientation"
@Override
public void onConfigurationChanged(Configuration myConfig)
{
super.onConfigurationChanged(myConfig);
int orient = getResources().getConfiguration().orientation;
switch(orient)
{
case Configuration.ORIENTATION_LANDSCAPE:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
case Configuration.ORIENTATION_PORTRAIT:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
default:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pepperonas.myapplication">
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Fragment mFragment;
private int mSelected = -1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate " + "");
// null check not realy needed - but just in case...
if (savedInstanceState == null) {
initUi();
// get an instance of FragmentTransaction from your Activity
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
/*IMPORTANT: Do the INITIAL(!) transaction only once!
* If we call this everytime the layout changes orientation,
* we will end with a messy, half-working UI.
* */
mFragment = FragmentOne.newInstance(mSelected = 0);
fragmentTransaction.add(R.id.frame, mFragment);
fragmentTransaction.commit();
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged " +
(newConfig.orientation
== Configuration.ORIENTATION_LANDSCAPE
? "landscape" : "portrait"));
initUi();
Log.i(TAG, "onConfigurationChanged - last selected: " + mSelected);
makeFragmentTransaction(mSelected);
}
/**
* Called from {@link #onCreate} and {@link #onConfigurationChanged}
*/
private void initUi() {
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate instanceState == null / reinitializing..." + "");
Button btnFragmentOne = (Button) findViewById(R.id.btn_fragment_one);
Button btnFragmentTwo = (Button) findViewById(R.id.btn_fragment_two);
btnFragmentOne.setOnClickListener(this);
btnFragmentTwo.setOnClickListener(this);
}
/**
* Not invoked (just for testing)...
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "onSaveInstanceState " + "YOU WON'T SEE ME!!!");
}
/**
* Not invoked (just for testing)...
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.d(TAG, "onSaveInstanceState " + "YOU WON'T SEE ME, AS WELL!!!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume " + "");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause " + "");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy " + "");
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_fragment_one:
Log.d(TAG, "onClick btn_fragment_one " + "");
makeFragmentTransaction(0);
break;
case R.id.btn_fragment_two:
Log.d(TAG, "onClick btn_fragment_two " + "");
makeFragmentTransaction(1);
break;
default:
Log.d(TAG, "onClick null - wtf?!" + "");
}
}
/**
* We replace the current Fragment with the selected one.
* Note: It's called from {@link #onConfigurationChanged} as well.
*/
private void makeFragmentTransaction(int selection) {
switch (selection) {
case 0:
mFragment = FragmentOne.newInstance(mSelected = 0);
break;
case 1:
mFragment = FragmentTwo.newInstance(mSelected = 1);
break;
}
// Create new transaction
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.frame, mFragment);
/*This would add the Fragment to the backstack...
* But right now we comment it out.*/
// transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* @author Martin Pfeffer (pepperonas)
*/
public class FragmentOne extends Fragment {
private static final String TAG = "FragmentOne";
public static Fragment newInstance(int i) {
Fragment fragment = new FragmentOne();
Bundle args = new Bundle();
args.putInt("the_id", i);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView " + "");
return inflater.inflate(R.layout.fragment_one, container, false);
}
}
<activity
android:name=".Test"
android:configChanges="orientation|screenSize"
android:screenOrientation="landscape" >
</activity>
@Override
public void onSaveInstanceState(Bundle outState) {
/*Save your data to be restored here
Example : outState.putLong("time_state", time); , time is a long variable*/
super.onSaveInstanceState(outState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState!= null){
/*When rotation occurs
Example : time = savedInstanceState.getLong("time_state", 0); */
} else {
//When onCreate is called for the first time
}
}
android:configChanges="keyboardHidden|orientation"
android:configChanges="keyboardHidden|orientation|screenSize"
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//Handle rotation from landscape to portarit mode here
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
//Handle rotation from portrait to landscape mode here
}
}
android:screenOrientation="portrait"
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outPersistentState.putBoolean("key",value);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getBoolean("key");
}
<activity android:name=".Youractivity"
android:configChanges="orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation"
android:configChanges="keyboardHidden|orientation"
class MyViewModel : ViewModel() {