描述activity中savedInstanceState来源的方法


我们在写一个自己的Activity的时候需要注意:  
1、都必须extends Activity(或者其子类);  
2、必须在方法onCreate中存在一条这样的语句:super.onCreate(也就是调用Activity的onCreate方法),对于super.onCreate方法放的位置要求不是很高,只要被调用了就可以了,super.onCreate主要是加载一些组件。  
如下面:  
import android.app.Activity;
import android.os.Bundle; 
public class TargetActivity extends Activity { 
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

setContentView...
}
}

需要引起注意的是:  
1、参数Bundle savedInstanceState来自何处?  
2、为何super.onCreate(savedInstanceState)语句的缺失会带给应用致命要害。  
也许熟悉源码的会发现,其实在Instrumentation类中的方法callActivityOnCreate方法,前面的调用过程略过,主要是在ActivityThread的方法performLaunchActivity中调用了Instrumentation类中的方法callActivityOnCreate方法,继而调用了TargetActivity中的onCreate方法。  
步骤:  
1、在ActivityThread中的方法performLaunchActivity调用了mInstrumentation.callActivityOnCreate(activity, r.state);  
2、Instrumentation类中的方法callActivityOnCreate方法,源码如下:  
/**
* Perform calling of an activity's {@link Activity#onCreate} method. The
* default implementation simply calls through to that method.

* @param activity
*            The activity being created.
* @param icicle
*            The previously frozen state (or null) to pass through to
*            onCreate().
*/
public void callActivityOnCreate(Activity activity, Bundle icicle) {
if (mWaitingActivities != null) { 
synchronized (mSync) {
final int N = mWaitingActivities.size();
for (int i = 0; i < N; i++) {
final ActivityWaiter aw = mWaitingActivities.get(i);
final Intent intent = aw.intent; 
if (intent.filterEquals(activity.getIntent())) {
aw.activity = activity;
mMessageQueue.addIdleHandler(new ActivityGoing(aw));
}
}
}
}
//?????activity引用是TargetActivity对象
activity.performCreate(icicle); 
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i = 0; i < N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i); 
am.match(activity, activity, activity.getIntent());
}
}
}
}

再次看方法activity.performCreate(icicle),其中的方法是通过activity,这个activity,形如:Activity activity = 子Activity的对象(其实也就是Java中的一种多态形式)。  
在Activity类中的方法performCreate(icicle),源码如下:  
final void performCreate(Bundle icicle) {

onCreate(icicle);

mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);

mFragments.dispatchActivityCreated();
}

注意:在performCreate方法中调用的onCreate方法是TargetActivity中的onCreate方法,那么到此TargetActivity中的方法onCreate方法中的参数Bundle savedInstanceState也就知道来源了,此时,TargetActivity中的方法也就被调用了。  
再次看TargetActivity中的方法onCreate:  
public class TargetActivity extends Activity { 
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

setContentView...方法

}

第一件事情便是super.onCreate(savedInstanceState),其实这条语句放在子类中的onCreate方法中的任何位置都可,问题只是super.onCreate(savedInstanceState)必须要被执行,所以,最好也就是放在第一行,看起来比较明确。还有就是调用了setContentView方法。在Activity中的setContentView方法,源码如下:  
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initActionBar();
}

与WindowManager、PhoneWindow等等进行联系。  
回到super.onCreate(savedInstanceState),来到Activity的onCreate(savedInstanceState)方法,源码如下:  
/**
* Called when the activity is starting. This is where most initialization
* should go: calling {@link #setContentView(int)} to inflate the activity's
* UI, using {@link #findViewById} to programmatically interact with widgets
* in the UI, calling
* {@link #managedQuery(android.net.Uri , String[], String, String[], String)}
* to retrieve cursors for data being displayed, etc.

* <p>
* You can call {@link #finish} from within this function, in which case
* onDestroy() will be immediately called without any of the rest of the
* activity lifecycle ({@link #onStart}, {@link #onResume}, {@link #onPause}
* , etc) executing.

* <p>
* <em>Derived classes must call through to the super class's
* implementation of this method.  If they do not, an exception will be
* thrown.</em>
* </p>

* @param savedInstanceState
*            If the activity is being re-initialized after previously being
*            shut down then this Bundle contains the data it most recently
*            supplied in {@link #onSaveInstanceState}. <b><i>Note:
*            Otherwise it is null.</i></b>

* @see #onStart
* @see #onSaveInstanceState
* @see #onRestoreInstanceState
* @see #onPostCreate
*/
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE)
Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
if (mLastNonConfigurationInstances != null) {
mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
}
if (mActivityInfo.parentActivityName != null) {
if (mActionBar == null) {
mEnableDefaultActionBarUp = true;
} else {
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
}
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments
.restoreAllState(
p,
mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.fragments
: null);
}

mFragments.dispatchCreate();

getApplication().dispatchActivityCreated(this, savedInstanceState);
mCalled = true;
}
 
在TargetActivity中重写了onCreate方法,而在Activity中的onCreate方法中已经对一些基本的基础进行了操作,如果子类没有super.onCraete方法的调用,会导致子类中的onCreate方法功能不全,从而出现错误。  
额外问题:onCreate中的savedInstanceState有何具体作用?具体例子?


在activity的生命周期中,只要离开了可见阶段,或者说失去了焦点,activity就很可能被进程终止了!,被KILL掉了,,这时候,就需要有种机制,能保存当时的状态,这就是savedInstanceState的作用。  
当一个Activity在PAUSE时,被kill之前,它可以调用onSaveInstanceState()来保存当前activity的状态信息(在paused状态时,要被KILLED的时候)。用来保存状态信息的Bundle会同时传给两个method,即onRestoreInstanceState() and onCreate().  
示例代码如下:  
package com.myandroid.test;  
import android.app.Activity;  
import android.os.Bundle;  
import android.util.Log;  
public class AndroidTest extends Activity {  
     private static final String TAG = "MyNewLog";  
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        // If an instance of this activity had previously stopped, we can  
        // get the original text it started with.  
        if(null != savedInstanceState)  
        {  
            int IntTest = savedInstanceState.getInt("IntTest");  
            String StrTest = savedInstanceState.getString("StrTest");  
            Log.e(TAG, "onCreate get the savedInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);          
        }  
        setContentView(R.layout.main);  
        Log.e(TAG, "onCreate");  
    }  
     
    @Override  
    public void onSaveInstanceState(Bundle savedInstanceState) {  
        // Save away the original text, so we still have it if the activity  
        // needs to be killed while paused.  
      savedInstanceState.putInt("IntTest", 0);  
      savedInstanceState.putString("StrTest", "savedInstanceState test");  
      super.onSaveInstanceState(savedInstanceState);  
      Log.e(TAG, "onSaveInstanceState");  
    }  
     
    @Override  
    public void onRestoreInstanceState(Bundle savedInstanceState) {  
      super.onRestoreInstanceState(savedInstanceState);  
      int IntTest = savedInstanceState.getInt("IntTest");  
      String StrTest = savedInstanceState.getString("StrTest");  
      Log.e(TAG, "onRestoreInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);  
    }  
}  
更多  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里提供一个简单的Demo,介绍如何通过startActivity方法启动新Activity: 1. 在Android Studio创建一个新的项目,选择Empty Activity作为模板。 2. 在activity_main.xml文件添加一个按钮控件: ``` <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动新Activity" /> ``` 3. 在MainActivity.java文件添加代码,为按钮添加点击事件监听器,并在监听器启动新的Activity: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取按钮控件 Button button = findViewById(R.id.button); // 为按钮添加点击事件监听器 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 创建Intent对象 Intent intent = new Intent(MainActivity.this, NewActivity.class); // 启动NewActivity startActivity(intent); } }); } } ``` 在上述代码,我们首先获取了一个按钮控件,然后为该按钮添加了一个点击事件监听器。当用户点击按钮时,会创建一个Intent对象,并将要启动的Activity类NewActivity作为参数传入Intent构造函数。最后,调用startActivity方法启动NewActivity。 4. 在NewActivity.java文件添加一些布局和逻辑代码,以便展示一些内容: ```java public class NewActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_new); // 获取TextView控件 TextView textView = findViewById(R.id.textView); // 设置TextView的文本 textView.setText("这是新Activity"); } } ``` 在上述代码,我们为新的Activity添加了一个TextView控件,并设置了该控件的文本。 5. 运行应用程序,点击按钮,可以看到新的Activity被启动,并展示了相应的内容。 通过上述Demo,我们可以了解到如何使用startActivity方法启动新的Activity
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值