活动的基本用法
创建活动
首先创建一个空项目,右击com.example.activitytest包→New→Activity→Empty Activity,弹出一个创建活动的对话框。将活动命名,并且不要勾选Generate Layout File和Launcher Activity   创建任何活动都应该重写onCreate() 方法,Android Studio已经自动重写好。
创建和加载布局
右击app/src/main/res目录→New→Directory会弹出一个目录窗口,创建一个layout目录,然后对着layout右键→Newyou→Layout resource file会弹出新建布局资源文件的窗口,我们命名为first_layout,根元素默认LinearLayout,这时就会看到布局编辑器。  我们在这里添加一个按钮
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"/>
</LinearLayout>
预览结果如下  这里添加了一个Button元素,并且添加了几个元素,android:id 是给当前的元素定义一个唯一的标识符,之后可以在代码中对该元素操作。XML定义使用@id/id_name 的语法。 接下来就要在在活动中加载这个布局,回到FirstActivity,在OnCreate()中加入代码
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
}
}
在AndroidMainfest文件中注册
活动声明要放在<application> 标签内,这里是通过<activity> 标签来对活动进行注册的,在<activity> 标签内我们使用了android:name
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Activitytest">
<activity android:name=".FirstActivity"></activity>
</application>
在<activity> 内部添加<intent-filter> 标签,除此之外,我们还可以使用android:label 指定活动中标题栏的内容
<activity
android:name=".FirstActivity"
android:label="This is FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
 标题栏下面就是在布局文件first_layout.xml中编写界面
活动中使用Toast
Toast是系统提供的一种提醒方式,这些信息提醒一段时间后就会消失。 首先要定义一个弹出Toast的触发点,利用之前建立好的按钮来创立。 在onCreate() 中添加如下代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Toast.makeText(FirstActivity.this,"You clicked Button 1",
Toast.LENGTH_SHORT).show();
}
});
}
在活动中,通过findViewById() 方法获取到在布局文件中定义的元素,这里我们传入R.id.button_1 ,来获得按钮实例,这个值是刚才在first_ layout.xml 中通过android:id 属性指定的。findViewById() 方法返回的是一个View 对象,我们需要向下转型将它转成Button对象。得到按钮的实例之后,我们通过调用setOnClickListener() 方法为按钮注册一个 监听器,点击按钮时就会执行监听器中的onClick() 方法。因此,弹出Toast的功能当然是要在onClick() 方法中编写了。
Toast 的用法非常简单,通过静态方法makeText() 创建出一个Toast对象,然后调用show() 将Toast显示出来就可以了。这里需要注意的是,makeText()方法需要传入3个参数。第一个参数是Context ,也就是Toast要求的上下文,由于活动本身就是一个Context对象,因此这里直接传人FirstActivity. this 即可。第二个参数是Toast显示的文本内容,第三个参数是Toast 显示的时长,有两个内置常量可以选择Toast. LENGTH SHORT 和Toast. LENGTH LONG 。 
在活动中使用Menu
首先在res目录下新建一个menu文件夹,右击res目录→New→Directory, 输人文件夹名menu, 点击OK。接着在这个文件夹下再新建一个名叫main的菜单文件,右击menu 文件夹→New →Menu resource file 然后再main.xml 中添加如下代码
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/add_item"
android:title="Add"/>
<item
android:id="@+id/remove_item"
android:title="Remove"/>
</menu>
这里我们创建了两个菜单项,其中<item> 标签就是用来创建具体的某一个菜单项,然后通过android:id 给这个菜单项指定一个唯一的标识符,通过android:title 给这个菜单项指定一个名称。 重写onCreateOptionMenu() 方法
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
通过getMenuInflater() 方法能够得到MenuInflater对象,再调用它的inflate() 方法就可以给当前活动创建菜单了。inflate() 方法接收两个参数,第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入R. menu . main 。第二个参数用于指定我们的菜单项将添加到哪一个Menu对象当中,这里直接使用onCreateOptionsMenu( ) 方法中传人的menu参数。然后给这个方法返回true,表示允许创建的菜单显示出来,如果返回了false, 创建的菜单将无法显示。 再定义菜单响应事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_item:
Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeText(this, "you clicked Remove", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
在onOptionsItemSelected() 方法中,通过调用item. getItemId( ) 来判断我们点击的是哪一个菜单项,然后给每个菜单项加人自己的逻辑处理,这里我们就活学活用,弹出一个刚刚学会的Toast 

使用Intent在活动间穿梭
Intent可以实现在两个不同活动之间跳转
显式Intent
1.获得Intent实例,例:Intent intent=new Intent(Context,Class(指定想要启动的目标活动))。
2.调用startActivity(Intent)方法启动目标活动。
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
这里的Context上下文可以理解为启动活动的一个环境。  SecondActivity界面
隐式Intent
用活动的配置信息来判断要启哪一个活动
1.给要启动的活动配置action 和category 信息。
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.activitytest.MY_CATEGORY" />
</intent-filter>
</activity>
2.获得Intent实例 3.调用intent.addCategory(String(category信息)) 方法给Intent配置category信息。 4.调用startActivity(Intent) 方法启动活动。
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
Intent intent = new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("com.example.activitytest.MY_CATEGORY");
startActivity(intent);
}
});
注意:只有action于category信息同时匹配才会启动相应活动,每个活动只能配置一个action信息,但可以配置多个category信息。
向下活动传递数据
在启动活动的时候可以传递数据 1.调用putExtra() 方法 2.书写要传入的数据
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
String data ="Hello SecondActivity";
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);
}
});
3.在下一个活动中实例化Intent并调用getStringExtra() 方法,传入键值,即可得到数据
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);
}
打开logcat 查看信息 
返回数据给上一个活动
1.调用startActivityForResult() 方法,用于启动活动的,但这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);
}
});
2.在下一个活动注册一个事件去实现该效果 3.调用setResult() 专门用于向上一个活动返回数据的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Button button2 = (Button)findViewById(R.id.button_2);
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK,intent);
finish();
}
});
}
4.在第一个活动中,重写onActivityResult() 方法,通过检查requestCode的值来判断数据来源,再通过resultCode的值来判断处理结果是否成功,最后从打data中打印出来。
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity", returnedData);
}
break;
default:
}
}
活动的生命周期
返回栈
Android是使用任务( Task)来管理活动的,一个任务就是一-组存放在栈里的活动的集 合,这个栈也被称作返回栈( Back Stack )。栈是一种后进先出的数据结构,在默认情况下,每当 我们启动了一个新的活动,它会在返回栈中人栈,并处于栈顶的位置。而每当我按下Back键 或调用finish() 方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会 重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。 
活动状态
每个活动在其生命周期中最多可能会有4个状态。
- 1.运行状态
当一个活动位于返回栈的栈顶时,这是活动就处于运行状态。 - 2.暂停状态
当一个活动不再处于栈顶位置,但仍然可见时,这时活动就会处于暂停状态。 - 3.停止状态
当一个活动不再处于栈顶位置,且完全不可见时,就进入了停止状态。 - 4.销毁状态
当一个活动自从返回栈中移除后就变成了销毁状态。
活动的生存期
onCreate() 第一次创建时候调用,在这个方法中完成活动的初始化操作,比如加载布局、绑定事件。onStart() 该方法在活动由不可见变为可见时调用。onResume() 该方法在活动准备与用户进行交互时调用,此时活动一定处于栈顶且处于运行状态。onPause() 该方法在系统准备去启动或恢复另一个活动时调用。该方法的执行速度一定要快,否则会影响到新栈顶活动的使用。onStop() 该方法在活动完全不可见时调用,与onPause()方法的区别在于,若启动的新活动是一个对话框活动,那么onPause()方法会得到执行,而onStop()方法并不会执行。onDestroy() 该方法会在活动销毁前执行,之后活动的状态就会变为销毁状态。onRestart() 该方法会在活动由停止状态变为运行状态之前调用,也会就是活动被重新启动了。 
活动被回收了怎么办
如果一个活动进入了停止状态,那么该活动是有可能被系统回收的,因此可能会导致数据丢失。 1.重写onSaveInstanceState() 方法,该方法可以保证在活动被回收之前获得调用,可以在其中调用putString(键,值) 方法来保存数据。
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("data_key",tempData);
}
2.在活动的onCreate() 方法中调用getString(键) 方法取出数据进行恢复。
if(savedInstanceState!=null){
String name=savedInstanceState.getString("name");
}
活动的启动模式
活动共有4种启动模式,分别是standard,singleTop,singleTask,singleInstance,可以在AndroidManifest.xml中通过给< activity > 标签指定android:launchMode 属性来选择启动模式。
-
standard: 默认模式,每当启动一个新的活动,就会在返回栈中入栈,并处于栈顶位置。该模式下无论这个活动是否在返回栈中存在,每次启动都会创建该活动的新实例。  -
singleTop: 该模式下,每当启动一个新的活动,如果发现返回栈的栈顶已是该活动,则可以直接使用它而不会再创建新的实例。  -
singleTask: 该模式下,每当启动一个新的活动,系统首先会在返回栈中检查是否存在该活动的实例,若存在就直接使用,并让该活动之上的所有活动出栈,若不存在则创建新的实例。  -
singleInstance 该模式下的活动会启用一个新的返回栈来管理这个活动。这个模式解决了其它程序和我们的程序共享一个活动实例的问题。 
|