Android四大组件之Activity

Activity

源码位置:frameworks/base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback


建立、配置和使用Activity

  • 配置Activity
Activity需要在AndroidManifest.xml文件中进行配置
<activity
   android:name=".MainActivity"
   android:exported="true"
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:launchMode="standard" >
   <intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
       <category android:name="android.intent.category.HOME" />
       <category android:name="android.intent.category.DEFAULT" >
   </intent-filter>
   <intent-filter >
       <action android:name="com.example.test_action" />
       <category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
   <meta-data
       android:name="com.example.test"
       android:value="test" />
</activity>

<!-- 
--exported:是否运行被其他程序调用
--android:configChanges="orientation|keyboardHidden|screenSize" :旋转屏幕后,Activity不会重新走生命周期
--launchMode:加载模式,包含四种:standard,singleTop,singleTask,singleInstance
--<action android:name="android.intent.action.MAIN" /> :程序入口
--<category android:name="android.intent.category.LAUNCHER" /> :显示在launcher中
--<category android:name="android.intent.category.HOME" /> :launcher应用
--<category android:name="android.intent.category.DEFAULT" > :如果支持隐式启动在没有category情况下,必须加上这个
--meta-data :提供额外信息
-->
  • <meta-data>信息获取

private String getMetaInfo() {
    ActivityInfo activityInfo = null;
    try {
        activityInfo = getPackageManager().getActivityInfo(
                new ComponentName(this, MainActivity.class), PackageManager.GET_META_DATA);
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
    Bundle bundle = activityInfo.metaData;
    String meta = bundle.getString("com.example.test");
    return meta;
}

Activity数据传递

  • 数据直接封装到intent中(本质上还是会封装到Bundle中)
//------发送------
intent.putExtra("name", "zhangsan");
startActivity(intent);
//------接收------
Intent intent = getIntent();
String name = intent.getStringExtra("name");
  • 使用Bundle封装数据
//------发送------
Bundle bundle = new Bundle();
bundle.putInt("age", 22);
intent.putExtras(bundle);
startActivity(intent);
//------接收------
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
int age = bundle.getInt("age");
  • 传递List<String>和List<Integer>
//------发送------
ArrayList<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
Intent intent = new Intent();
intent.putStringArrayListExtra("list", list);
startActivity(intent);
//------接收------
Intent intent = getIntent();
ArrayList<String> list = (ArrayList<String>) intent.getStringArrayListExtra("list");
  • 使用Serializable和Parcelable两种方式传递Object
//------发送------
bundle.putSerializable(key, object);
bundle.putParcelable(key, object);
//------接收------
object = (Object) getIntent().getSerializableExtra(key);
object = (Object) getIntent().getParcelableExtra(key);


Activity启动方式

  • 显式启动

构造方法传入Component

Intent intent = new Intent(this, OtherActivity.class);
startActivity(intent);

setClass方法

Intent intent = new Intent();
intent.setClass(this, OtherActivity.class);
startActivity(intent);

setClassName方法

Intent intent = new Intent();
intent.setClassName(this, "com.example.test.OtherActivity");
startActivity(intent);

setComponent方法

Intent intent = new Intent();
intent.setComponent(new ComponentName(this, OtherActivity.class));
startActivity(intent);
  • 隐式启动
(没设数据参数的情况下)只要Intent中的Action和Category都出现在Intent-Filter中,就能与之匹配,否则匹配失败
Intent intent = new Intent();
intent.setAction("com.example.test_action");
intent.addCategory("com.example.test_category");
intent.setDataAndType(Uri.parse("test://www.example.cn/hello"), "image/jpeg");
startActivity(intent); // 方法内部为Intent添加了android.intent.category.DEFAULT类别


Activity启动方法

  • 两种启动方式
startActivity
startActivityForResult //可以回传数据
  • startActivityForResult
public void startActivityForResult(Intent intent, int requestCode)
protected void onActivityResult(int requestCode, int resultCode, Intent data)
public final void setResult(int resultCode, Intent data)
// 启动OtherActivity
Intent intent = new Intent(this, OtherActivity.class);
startActivityForResult(intent, 0); // requestCode == 0

// OtherActivity关闭后,会回调onActivityResult方法处理返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 0 && resultCode == RESULT_OK) {
        String string = data.getStringExtra("data");
    }
    super.onActivityResult(requestCode, resultCode, data);
}

// OtherActivity关闭前,调用setResult设置要回传的数据
Intent data = getIntent();
data.putExtra("data", "hello world");
setResult(RESULT_OK, data); // resultCode == RESULT_OK
finish();


关闭Activity方式

public void finish()
public void finishActivity(int requestCode) //关闭其他以startActivityForResult启动的activity
public void finishAffinity() //结束同一个栈中的所有activity


关闭应用方法

//杀进程
Process.killProcess(Process.myPid());
//退出java 虚拟机
System.exit(0);
//强制杀掉与包相关的一切执行
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
manager.killBackgroundProcesses(getPackageName());


Activity的生命周期

  • Activity的3个状态
运行状态、暂停状态、停止状态

运行(激活)状态:处于栈顶(屏幕前台时,可以响应用户操作)
暂停状态:当Activity上面有另一个Activity,上面的activity没有完全覆盖它,或者上面的activity是透明的,下方的activity仍然对用户可见;是存活状态,如果内存不足时,会杀死这个activity;
停止状态:当activity完全被令一个activity覆盖时,处于停止状态。它仍然保留所有的状态和成员信息,然而对用户是不可见的,所以它的窗口将被隐藏,如果其他地方需要内存,系统经常会杀死这个activity。
  • 生命周期中的7个方法
protected void onCreate(Bundle savedInstanceState) //初始化操作,这时activity界面还没有显示出来
protected void onStart() 
protected void onResume() //activity界面显示出来
protected void onPause() //被其他Activity覆盖其上或锁屏或按HOME键
protected void onRestart() //activity被重新唤起时首先调用该方法
protected void onStop()
protected void onDestroy()

启动到退出:
onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy

启动,锁屏,解锁/启动,按HOME键,再次进入
onCreate -> onStart -> onResume -> onPause -> onStop -> onRestart -> onStart -> onResume
Android四大组件之Activity_第1张图片
  • 非生命周期方法
protected void onSaveInstanceState(Bundle outState)
//当内存不足或按HOME键或锁屏时会回调该方法保存一些临时性状态
//由运行状态进入暂停状态或停止状态也会回调该方法
//当按返回键或自动销毁activity时不会回调该方法
protected void onRestoreInstanceState(Bundle savedInstanceState)
//该方法不一定与onSaveInstanceState成对调用
//只有在activity确实被销毁后,再次进入时调用
//onRestoreInstanceState的bundle参数也会传递到onCreate方法中,也可以选择在onCreate方法中做数据还原
当屏幕方向发生了改变,Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据,可以重写这两个方法
//被摧毁前缓存一些数据
@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("test", "hello");
    super.onSaveInstanceState(outState);
}
//被重新创建后恢复缓存的数据,
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    String saveData = savedInstanceState.getString("test");
    super.onRestoreInstanceState(savedInstanceState);
}
//被重新创建后恢复缓存的数据
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String info = savedInstanceState.getString("test");
    }
}


Activity启动模式(LaunchMode)

  • 四种启动模式
standard / singleTop / singleTask / singleInstance
  • standard
默认模式,每次激活Activity都会创建Activity实例,并放入任务栈中
  • singleTop
如果在任务的栈顶正好存在该Activity的实例,就重用该实例,否则就会创建新的实例并放入栈顶
即使栈中已经存在该Activity实例,只有不在栈顶,都会创建实例
会回调onNewIntent()
  • singleTask
如果在栈中已经有该Activity的实例,就重用该实例,重用时会让该实例回到栈顶,因此在它上面的实例将被移出栈
如果栈中不存在该实例,将会创建新的实例放入栈中
会回调onNewIntent()
  • singleInstance
在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例
一旦该模式的Activity的实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例
其效果相同于多个应用共享一个应用,不管谁激活该Activity都会进入同一个应用中
会回调onNewIntent()


使用adb获取activity栈信息

adb shell dumpsys activity
adb shell dumpsys activity activities
adb shell dumpsys activity activities |grep -i run



你可能感兴趣的:(Android四大组件之Activity)