Android菜鸟的成长笔记(7)——什么是Activity
来源:互联网 发布:香港大学商学院 网络 编辑:程序博客网 时间:2024/06/05 18:29
前面我们做了一个小例子,在分析代码的时候我们提到了Activity,那么什么是Activity呢?
Activity是Android应用程序提供交互界面的一个重要组件,也是Android重要组件之一(另外3个是Service、BroadcastReceiver和ContentProvider)。
与开发Web应用时建立Servlet类相似,建立自己的Activity也需要继承Activity基类,当然,在不同应用场景下,有时也要求继承Activity的子类。例如如果应用程序界面只包括列表,则可以让应用程序继承ListActivity;如果应用程序界面需要实现标签页效果,则可以让应用程序继承TabActivity。
Activity的启动过程
1、建立activity类及定义属性和内部方法
2、注册activity在manifest文件中
3、在启动函数onCreate中实现业务
3.1 界面定义layout
3.2界面的绑定setContentView()
- package com.example.myfirstapp;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- }
这是我们前面的Activity,下面我们来实现一个LauncherActivity
LauncherActivity继承了ListActivty,因此它本质上也是一个开发列表界面的Activity,但它开发出来的列表界面与普通列表界面有所不同。它开发出来的列表界面中的每个列表项都对应一个Intent,因此当用户单击不同的列表项时,应用程序会自动启动对应的Activity。
- package com.example.testactivity;
- import android.app.LauncherActivity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.widget.ArrayAdapter;
- public class MainActivity extends LauncherActivity {
- // 定义两个Activity的名称
- String[] names = { "选项一", "选项二" };
- // 定义两个Activity对应的实现类
- Class<?>[] clazzs = { ActivityTest1.class, ActivityTest2.class };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // setContentView(R.layout.activity_main);
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_list_item_1, names);
- // 设置该窗口显示列表所需的Adapter
- setListAdapter(adapter);
- }
- @Override
- protected Intent intentForPosition(int position) {
- // TODO Auto-generated method stub
- return new Intent(MainActivity.this,clazzs[position]);
- }
- }
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity
- android:name=".ActivityTest1">
- </activity>
- <activity
- android:name=".ActivityTest2">
- </activity>
- </application>
startActivity(Intent intent) :启动其他Activity
startActivityForResult(Intent intent, int requestCode) :以指定的请求码启动Activity,而且程序将会等到新启动Activity的结果(通过重写onActivityResult方法获取)
Android为关闭Activity提供了如下两个方法
finish() :结束当前Activity
finishActivity(int requestCode) :结束以startActivityForResult(Intent intent, int requestCode)方法启动的Activity
下面我们来看看Activity的生命周期
归纳起来Activity大致有如下4个状态
1、活动状态(runing) :当前activity处于前台,用户可见,可以获得焦点
2、暂停状态(pause):其他activity位于前台,该activity依然可见,只是不能获得焦点
3、停止状态(stop):该activity不可见,失去焦点
4、销毁状态(destory):该activity结束,或activity所在的Dalvik进程被结束
接下来再来看看配置Activity时候的android:launchMode属性
当我们启动一个应用的时候实际上Dalvik虚拟器会创建一个Task,而每个进程都有一个id,虚拟机是以栈的形式来管理每个Task的,先启动的activity放在Task栈底,后启动的activity放在Task栈顶。
Activity的加载模式,就负责管理实例化、加载activity的方式(也就是上面的android:launchMode设置)
1、standard模式
每次通过这种模式启动activity时,android总会为目标activity创建一个新的实例,并将该activity添加到栈中。
这种模式不会产生新的Task,新activity将被添加到原有的Task中。
例如:
- package com.example.helloword;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- private static final String TAG = "MainActivity";
- Button button;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Log.i(TAG, "" + getTaskId());
- button = (Button) findViewById(R.id.main_button);
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- //创建启动MainActivity的Intent
- Intent intent = new Intent(MainActivity.this, MainActivity.class);
- startActivity(intent);
- }
- });
- }
- }
这证明了每次都调用了onCreate方法,但是Task是同一个。
2、singleTop模式
与standard模式不同的是当将要被启动的目标Activity已经位于Task栈顶时,系统不会重新创建activity实例。
如果将上面代码中的Activity的启动模式改为singleTop,点击多次,都不会再次调用onCreate方法。
3、singleTask模式
采用这种模式的Activity在同一个Task内只有一个实例。分为如下三种情况:
(1)如果将要启动的目标Activity不存在,体统会创建目标activity的实例,并将它加入Task栈顶
(2)如果将要启动的目标activity已经位于Task栈顶,此时与singleTop模式的行为相同
(3)如果将要启动的目标activity已经存在、但是没有位于Task栈顶,系统将会把位于该activity上面的所有activity移出Task栈,从而使目标activity转入栈顶
4、singleInstance模式
这种模式下,系统会保证无论哪个Task中启动目标activity,只会创建一个目标activity实例,并会使用一个全新的Task栈来装载activity实例。
接下来我们进入Android系统源代码看看Activity装载界面的过程
- /**
- * Set the activity content to an explicit view. This view is placed
- * directly into the activity's view hierarchy. It can itself be a complex
- * view hierarhcy.
- *
- * @param view The desired content to display.
- */
- public void setContentView(View view) {
- getWindow().setContentView(view);
- }
- @Override
- public void setContentView(View view, ViewGroup.LayoutParams params) {
- if (mContentParent == null) {
- installDecor();
- } else {
- mContentParent.removeAllViews();
- }
- mContentParent.addView(view, params);
- final Callback cb = getCallback();
- if (cb != null) {
- cb.onContentChanged();
- }
- }
如果根视图为null则创建一个window否则之间加载视图文件,这样我们就明白了,其实视图是加载到Window对象上的,接下来我们再来看一下如何将Activity和Window联系起来,其实在启动activity的时候会调用一个attach方法
- final void attach(Context context, ActivityThread aThread,
- Instrumentation instr, IBinder token, int ident,
- Application application, Intent intent, ActivityInfo info,
- CharSequence title, Activity parent, String id,
- Object lastNonConfigurationInstance,
- HashMap<String,Object> lastNonConfigurationChildInstances,
- Configuration config) {
- attachBaseContext(context);
- mWindow = PolicyManager.makeNewWindow(this);
- mWindow.setCallback(this);
- if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
- mWindow.setSoftInputMode(info.softInputMode);
- }
- mUiThread = Thread.currentThread();
- mMainThread = aThread;
- mInstrumentation = instr;
- mToken = token;
- mIdent = ident;
- mApplication = application;
- mIntent = intent;
- mComponent = intent.getComponent();
- mActivityInfo = info;
- mTitle = title;
- mParent = parent;
- mEmbeddedID = id;
- mLastNonConfigurationInstance = lastNonConfigurationInstance;
- mLastNonConfigurationChildInstances = lastNonConfigurationChildInstances;
- mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
- if (mParent != null) {
- mWindow.setContainer(mParent.getWindow());
- }
- mWindowManager = mWindow.getWindowManager();
- mCurrentConfig = config;
- }
总结起来有两点:
1、Activity构造的时候调用了attach绑定了一个窗体
2、Activity在setContentView的时候实际上是它所绑定的窗体设置contentView
- Android菜鸟的成长笔记(7)——什么是Activity
- Android菜鸟的成长笔记(7)——什么是Activity
- Android菜鸟的成长笔记——初识Activity
- Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值
- Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值
- Android菜鸟的成长笔记——第一个Activity 和 ADB
- Android菜鸟的成长笔记(20)——IntentService
- Android菜鸟的成长笔记(20)——IntentService
- Android菜鸟的成长笔记——Eclipse使用小结
- Android菜鸟的成长笔记——编码规范什么的
- Android菜鸟的成长笔记——ViewPager图片循环
- Android菜鸟的成长笔记——PopupMenu使用
- Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)
- Android菜鸟的成长笔记(15)—— Android中的状态保存探究(下)
- Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)
- Android菜鸟的成长笔记(15)—— Android中的状态保存探究(下)
- Android菜鸟的成长笔记(2)——第一个Android应用
- Android菜鸟的成长笔记(22)——Android进程间传递复杂数据(AIDL)
- jQuery EasyUI Datagrid性能优化专题
- Android - Binder机制 - ProcessState和IPCThreadState
- 【patterns】simple factory
- 个人面经
- codility上的问题(32) Nitrogenium 2013
- Android菜鸟的成长笔记(7)——什么是Activity
- 设置 UILabel 和 UITextField 的 Padding 或 Insets (理解UIEdgeInsets)
- 什么是夫妻?什么是家 ?
- apache Kafka概要介绍
- Error 130010: Resource pool ‘' asked for a dynamic IP but there were no more available
- Myeclipse下web项目改名,tomcat下不变的问题
- java 注解
- Unity3d+高通云识别应用
- Eclipse 中如何取得资源路径信息