Activity(活动)是Android四大组件之一;它跟用户直接面对面交互。首先重要的一点是你的每一个活动都要在清单文件中注册。
Intent是Android程序中各个组件之间进行交互的一种重要方式;它不仅可以指明当前组件想要执行的动作,还可以在不同的组件之间传递数据。分为显示Intent和隐式Intent。
显示Intent代码如下:
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
- 1
- 2
- 3
隐式Intent需要指定一系列更加抽象的action和category。
在清单文件中代码:
<activity android:name=".SecondActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="com.gyq.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.gyq.activitytest.MY_CATEGORY" />
</intent-filter>
</activity>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
FirstActivity中代码如下:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_first_button1:
Intent intent = new Intent("com.gyq.activitytest.ACTION_START");
intent.addCategory("com.gyq.activitytest.MY_CATEGORY");
startActivity(intent);
break;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
隐式Intent不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的共享成为了可能;代码如下:
1,直接跳转到拨号界面,只要按拨打键就可以了。
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:555"));
startActivity(intent);
- 1
- 2
- 3
2,直接跳转到百度网页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
- 1
- 2
- 3
向下一个活动传递数据:
1,FirstActivity.java中按钮点击事件中的代码,跳转到第二个界面:
String data = "亲爱的:你好么?";
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
//通过intent的将本界面的数据传递到第二个界面。
intent.putExtra("data",data);
startActivity(intent);
- 1
- 2
- 3
- 4
- 5
2,SecondActivity.java接收数据;
Intent intent = getIntent();
String content = intent.getStringExtra("data");
//content就是上个界面中data的内容。
Log.d(TAG, "onCreate: "+content);
- 1
- 2
- 3
- 4
返回数据给上一个活动:startAcitivityForResult()方法
1,活动一代码:
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String resultData = data.getStringExtra("result");
Log.d(TAG, "onActivityResult: "+resultData);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
2,活动二代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Button btn2 = (Button)findViewById(R.id.btn_second_button2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//传递数据给上一个activity。
Intent intent = new Intent();
intent.putExtra("result","亲爱的:我很好。");
setResult(RESULT_OK,intent);
finish();
}
});
}
//按返回键可以销毁当前界面,然后将数据回传到第一个界面。
@Override
public void onBackPressed() {
//传递数据给上一个activity。
Intent intent = new Intent();
intent.putExtra("result","亲爱的:我很好。");
setResult(RESULT_OK,intent);
finish();
}
Activity的生命周期,先上一张图:
onCreat()。每个活动中我们都会重写这个方法,它会在活动第一次创建的时候调用;可以在这里面完成获得初始化操作,如加载布局、初始化数据、绑定事件等。
onStart()。这个方法在活动由不可见变为可见的时候调用。
onResume()。这个方法在活动准备好和用户进行交互的时候调用。此时活动一定位于返回栈的栈顶,并且处于运行状 态。
onPause()。这个方法在系统准备去启动或恢复另一个活动的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放,以及保存一些关键的数据,但这个方法中不能执行太耗时的操作。
onStop()。这个方法在活动完全不可见的时候调用,它和onPause()方法的主要区别在于如果启动的新活动是一个对话框,那么onPause()方法会执行,而onStop()方法不会执行。
onDestroy()。这个方法在活动被销毁之前调用,之后活动的状态就是销毁状态。
onRestart()。这个方法在活动由停止状态变为运行状态之前调用。也就是活动被重新启动了。
面试题
1、一个Activity A跳转到另一个Activity B,其生命周期变化?
a,如果A被B完全遮挡,则A会执行:onPause(),onStop()。B会执行onCreate(),onStart(),onResume()方法。
b,如果B是对话框,那么A执行onPause()。B会执行onCreate(),onStart(),onResume()方法。
2、简述横竖屏切换时,Activity的生命周期?
1、新建一个Activity,并把各个生命周期打印出来
2、运行Activity,得到如下信息
onCreate–>
onStart–>
onResume–>
3、按crtl+f12切换成横屏时
onSaveInstanceState–>
onPause–>
onStop–>
onDestroy–>
onCreate–>
onStart–>
onRestoreInstanceState–>
onResume–>
4、再按crtl+f12切换成竖屏时,发现打印了两次相同的log
onSaveInstanceState–>
onPause–>
onStop–>
onDestroy–>
onCreate–>
onStart–>
onRestoreInstanceState–>
onResume–>
onSaveInstanceState–>
onPause–>
onStop–>
onDestroy–>
onCreate–>
onStart–>
onRestoreInstanceState–>
onResume–>
5、修改AndroidManifest.xml,把该Activity添加 Android:configChanges=”orientation”,执行步骤3
onSaveInstanceState–>
onPause–>
onStop–>
onDestroy–>
onCreate–>
onStart–>
onRestoreInstanceState–>
onResume–>
6、再执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged
onSaveInstanceState–>
onPause–>
onStop–>
onDestroy–>
onCreate–>
onStart–>
onRestoreInstanceState–>
onResume–>
onConfigurationChanged–>
7、把步骤5的android:configChanges=”orientation” 改成 android:configChanges=”orientation|keyboardHidden”,执行步骤3,就只打印onConfigChanged
onConfigurationChanged–>
8、执行步骤4
onConfigurationChanged–>
onConfigurationChanged–>
总结:
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
总结一下整个Activity的生命周期
补充一点,当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命周期不会有改变
Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState –> onPause –> onStop onRestart –>onStart—>onResume
Activity未被完全覆盖只是失去焦点:onPause—>onResume
活动的启动模式
Android中Activity的启动模式:
1,standard 是活动默认的启动模式;特点:系统不会在乎这个活动是否已经在返回栈中存在,每次启动这个活动都会创建该活动的一个新的实例。
2,singleTop 在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
3,singleTask 每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
4,singleInstance 会启用一个新的返回栈来管理这个活动。
活动的一些技巧:
1,当你刚进入一家公司,怎么才能知道打开的这个界面是哪个activity呢?我们先来创建一个BaseActivity.java,然后让所有的活动去继承这个类。查看日志就可以知道具体是哪个界面啦。
package com.gyq.activitytest;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
/**
* ${DESC}
* author: gyq
* create at 2016/12/9 14:20
*/
public class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, getClass().getSimpleName());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
随时随地退出程序;
1,首先创建一个集合类。中定义添加活动,移除活动的方法;然后BaseActivity中调用这两个方法。直接类名.就可以调用啦。
package com.gyq.activitytest;
import android.app.Activity;
import java.util.ArrayList;
import java.util.List;
/**
* ${DESC}
* author: 龚友强
* create at 2016/12/9 14:27
*/
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
public static void addActivity(Activity activity) {
activities.add(activity);
}
public static void removeActivity(Activity activity) {
activities.remove(activity);
}
public static void finishAll() {
for (Activity activity : activities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
如果你想在某个界面点击按钮就退出程序,则只需在这个按钮的点击事件中调用finishAll()这个方法。
https://blog.csdn.net/duoduo_11011/article/details/53541353