Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 解析Activity中的onCreate方法

解析Activity中的onCreate方法

編輯:關於Android編程

我們在寫一個自己的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.
*
*


* 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.
*
*


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

*


*
* @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}. Note:
* Otherwise it is null.

*
* @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);

}

}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved