是否可以检查是否由于方向更改而调用了 onCreate?

Posted

技术标签:

【中文标题】是否可以检查是否由于方向更改而调用了 onCreate?【英文标题】:Is that possible to check was onCreate called because of orientation change? 【发布时间】:2011-09-03 20:50:45 【问题描述】:

我需要在 onStart() 方法中采取不同的行动,具体取决于在结果中如何调用 onCreate() orientation change 或不是。可以查吗?

实际上,我需要在活动开始时执行something,除非用户改变方向

我需要清楚地区分用户刚刚切换到另一个应用程序并返回或更改设备方向的情况。

【问题讨论】:

【参考方案1】:

按照 Nahtan 的想法,我写了这个:

在 onCreate() 中:

if ( (oldConfigInt & ActivityInfo.CONFIG_ORIENTATION)==ActivityInfo.CONFIG_ORIENTATION ) 
    // ... was rotated
 else 
    // ... was not rotated

在 onDestroy() 中:

super.onDestroy();
oldConfigInt = getChangingConfigurations();

【讨论】:

【参考方案2】:
public class MyActivity extends Activity 
    boolean fromOrientation=false;
    SharedPreferences myPrefLogin;
    Editor prefsEditor;
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        prefsEditor = myPrefLogin.edit();
        myPrefLogin = this.getSharedPreferences("myPrefs", Context.MODE_WORLD_READABLE);
        fromOrientation = myPrefLogin.getString("fromOrient", false);

        if(fromOrientation) 
             // do as per need--- logic of orientation changed.
         else 
             // do as per need--- logic of default onCreate().
        
    

    @Override
    public Object onRetainNonConfigurationInstance() 
        prefsEditor.putString("fromOrient", true);
        prefsEditor.commit();
        return null;
    

    @Override
    protected void onDestroy() 
        if(fromOrientation) 
            prefsEditor.putString("fromOrient", false);
            prefsEditor.commit();
        
        super.onDestroy();
      

flag fromOrientation(告诉状态配置是否已更改) 上面我们已经通过defalut 完成了我们正在考虑onCreate() 不是通过改变方向来调用的。如果方向改变(onRetainNonConfigurationInstance()),那么我们优先设置标志值,让我们知道是否从方向调用onCreate()。 最后onDestroy() 我们再次重置了方向标志。

【讨论】:

这行不通了。请参阅developer.android.com/guide/topics/resources/…。【参考方案3】:

试试getChangingConfigurations。使用它来发现 Activity 何时因方向变化而被销毁,设置一个标志,并在调用 onCreate 时检查该标志。

这样做的好处是可以让您知道 Activity 重新启动的原因,而无需覆盖清单中的方向配置。

【讨论】:

根据参考文档,这种方法虽然不是100%可靠,但建议仅作为提示使用【参考方案4】:

只需检查捆绑包:当活动首次启动时,捆绑包将为空。如果有方向变化,它应该是非空的。

来自android docs:

如果 Activity 在之前关闭后重新初始化,则此 Bundle 包含它最近在 onSaveInstanceState(Bundle) 中提供的数据。注意:否则为空。

编辑:我不认为您必须在 onSaveInstanceState 中提供一个包,以便在方向更改后它不为空,但这将是微不足道的。

【讨论】:

实际上我需要做的是something,当活动开始时,除了用户改变方向的情况(从描述中复制) 然后在 onCreate 中检查 bundle 是否为空,如果是,则执行“某事”。 明白了;误解了您只是想识别第一个电话。在那种情况下,我想我有更好的答案,我会单独发布。 在我想启动一次的 Activity 中有一个 Timer 并且该 Activity 在再次启动之前完成时为我工作。【参考方案5】:

正如其他人所说,保存状态:

public class MyActivity extends Activity 
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        if(savedInstanceState == null) 
            // app started afresh, don't check orientation
            /* do application first-run stuff */
         else 
            // re-started, so check for orientation change
            boolean orientationChanged = false;
            if(savedInstanceState != null) 
                int lastOrientation = savedInstanceState.getInt("last_orientation");
                orientationChanged = (getOrientation() != lastOrientation);
            

            if(orientationChanged) 
                // orientation changed
                /* do stuff */
             else 
                // orientation has not changed
                /* do stuff */
            
        
    

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) 
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putInt("last_orientation", getOrientation());
    

    private int getOrientation() 
        // ...
    

【讨论】:

如果您最小化处于纵向模式的应用程序并从横向模式重新启动它,这将不起作用。在这种情况下,您将有不同的方向并触发您的 if 条件,这不应该按要求发生。 为什么需要确定用户是在 Activity 内部还是外部改变了方向? 因为当用户启动应用程序时我需要做一件事,而不是在他使用它时(比如更改设备的方向)。 检查用户是否重新启动游戏的最简单方法是检查savedInstanceState 是否为空(如Nathan 所建议的那样),您可以将其添加到上述代码中。我认为您已经被应用程序“打开”或“关闭”(例如 PC)的概念所困扰,而实际上,在 Android 中,您不应该区分这两种状态。 其实Nathan的回答绝对值得追!【参考方案6】:

您可以尝试以下方法。 在每个 onStart 上,您都可以保存当前方向(看看here)。 如果是第一次 onStart 调用,什么都不做,在其他调用上,检查方向是否改变并做你需要的。

private int m_currentOrientation = -1;

public void onStart()

   int oldOrientation = m_currentOrientation; // 
   m_currentOrientation = getCurrentOrientation(); // As in the link above
   if ((oldOrientation != -1) && (oldOrientation != m_currentOrientation))
   
       // Do what you need
   

【讨论】:

这不起作用,因为m_currentOreintation 始终是-1,因为在每个方向更改您的类活动的新实例都会实例化。 可以使用onSaveInstanceState,看这里:***.com/questions/151777/… Anyway onCreate() 不仅可以在方向更改后发生,而且在某些其他情况下也可以发生(例如,在应用程序中转到主屏幕并返回) 但在这种情况下,m_CurrentOrientation 将是相同的。 @Lior Ohana,oldOrientation 的值将始终相同,因为当配置更改时,整个活动会自行重新启动,因此 oldOrientation 保持不变。【参考方案7】:

在这种情况下,您为什么不自己处理配置更改(方向)。告诉android不要处理屏幕方向。

android:configChanges="keyboardHidden|orientation"

然后您只需覆盖 onConfigurationChanged 方法即可重新排列视图或任何需要完成的事情。留下你不想被处决的东西。

@Override
public void onConfigurationChanged(Configuration newConfig) 
  super.onConfigurationChanged(newConfig);
  //do your jobs 

【讨论】:

如果他希望纵向和横向模式有不同的布局,这将导致问题。 Android 在方向更改期间重新启动活动是有原因的。 这个方法还是可以设置不同的布局的。我们需要做的就是从新配置中检查方向。放入条件语句中。执行“setContentView(properlayout)”。无论如何,我确实同意“Android 在方向更改期间出于某种原因重新启动活动”这一事实。但这取决于我们做我们想要实现的目标。是吗? 如果您以这种方式处理旋转并从onConfigurationChanged 调用setContentView,您的视图状态不会被保存和恢复。例如,如果你有EditView,它的内容将被重置。【参考方案8】:

如果应用程序首次启动,mCurrentOrientation 将为 -1。

static int mCurrentOrientation = -1;

public void onStart()

   int oldOrientation = mCurrentOrientation; 
   mCurrentOrientation = getCurrentOrientation(); 
   if ((oldOrientation != -1) && (oldOrientation != mCurrentOrientation)) 
       // Do your something here.
   

如果我正确理解了您的问题,我认为这应该适合您。

【讨论】:

以上是关于是否可以检查是否由于方向更改而调用了 onCreate?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查向量是否面向相同的方向

是否可以鼓励线程排队而不强迫它?

是否可以控制 matplotlib 标记方向?

如何在 Unity C# 中检查对象是不是面向某个方向

windows 无法启动 SQL Server (MSSQLSERVER) 服务(位于本地计算机上)。错误 1069由于登入失败而无法启动

设置者不更改类中向量的数据