学而实习之 不亦乐乎

Android 中活动(Intent)用法

2023-08-16 20:42:53

一、活动用法及使用 Intent

1、使用显式 Intent

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

2、使用隐式 Intent

相比于显式 Intent,隐式 Intent 更加含蓄。它并不明确指定启动那一个 Intent ,而是指定了一系列更为抽象的 action 和 category 信息,然后由系统决定启动那一个 Intent 。

如,在 AndroidManifest.xml 文件中定义一个 Activity 如下:
 

<activity android:name=".TestActivity">
    <intent-filter>
        <action android:name="com.test.activitytest.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

在 Activity 中调用如下:

Intent intent = new Intent("com.test.activitytest.ACTION_START");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);

注意:一个 Intent 只能指定一个 action,但可以指定多个 category 。

3、隐式 Intent 应用实例

1)打开网页

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);

注意:这里可以在 <intent-filter> 中配置一个 <data> 标签,用于更精确地指定当前活动能够响应什么样类型的数据。
如下:
android:scheme。指定数据的协议,如 http
android:host。指定数据的主机名,如 www.baidu.com
android:port。指定数据的端口
android:path。指定主机名和端口后面的部分
android:mimeType。指定可以处理的数据类型。

当有多个程序可以响应这个 Intent 时,系统会弹出一个列表给用户,用于选择打开的方式。

二、活动间的数据传递

1、向下一个活动传递数据

从 FirstActivity 向 SecondActivity 传递数据

FirstActivity.java

btn1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String data = "Hello Second!";
        Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
        intent.putExtra("extra_data",data);
        startActivity(intent);
    }
});

SecondActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    
    Intent intent = getIntent();
    String data = intent.getStringExtra("extra_data");
    Log.d("SecondActivity",data);
}

2、向上一个活动返回数据
FirstActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first);
    btn1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
            startActivity(intent,1);
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    switch (requestCode) {
        case 1:
            if (requestCode == RESULT_OK) {
                String returnedData = data.getStringExtra("return_data");
                Log.d("FirstActivity",returnedData);
            }
            break;
        default:
            break;
    }
}

SecondActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    
    Button btn2 = findViewById(R.id.btn2);    
    btn2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.putExtra("return_data","Hello First");
            setResult(RESULT_OK,intent);
            finish();
        }
    });
}

三、活动的生命周期

掌握活动的生命周期对任何 Android开发者来说都非常重要,当你深入理解活动的生命 周期之后,就可以写出更加连贯流畅的程序,并在如何合理管理应用资源方面,你会发挥的 游刃有余。你的应用程序将会拥有更好的用户体验。

1.返回栈

Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动 的集合这个栈也被称作返回栈(Back Stack)。栈是一种后进先出的数据结构。
默认情况下,启动一个新的活动,会在返回栈中入栈,并处于栈顶位置。当我们按下 Back键或调用 finish()方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。

2.活动状态

运行状态:活动位于返回栈的栈顶时(系统最不愿意回收的 就是处于运行状态的活动,因为这会带来非常差的用户体验。)
暂停状态:当一个活动不再处于栈顶位置,但仍然可见时(比如某个活动上面新开了个对话框活动该活动就是暂停活动-系统也不愿意去回收这 种活动。)
停止状态:当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。(系统 仍然会为这种活动保存相应的状态和成员变量,但很容易被回收)
销毁状态:当一个活动从返回栈中移除后就变成了销毁状态(系统会最倾向于回收处于这种状 态的活动,从而保证手机的内存充足。)

3.创建活动的生存期

onCreate() :它会在活动 第一次被创建的时候调用用于加载布局、绑定事件等。
onStart():这个方法在活动由不可见变为可见的时候调用。
onResume():这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。
onPause(): 这个方法在系统准备去启动或者恢复另一个活动的时候调用。
onStop():  这个方法在活动完全不可见的时候调用。-----(如 果启动的新活动是一个对话框式的活动,那么 onPause()方法会得到执行,而 onStop() 方法并不会执行。)。
onDestroy():这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
onRestart():活动被重新启动时调用。

以上7个方法中除了onRestart()方法外,其它都是两两相对,从而又可以将活动分为3中生存期。
完整生存期:活动在onCreate()和onDestroy()之间所经历的,就是完整生存期,一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
可见生存期:活动在onStart()和onStop()之间所经历的就是可见生存期,在可见生存期内活动对用户是可见的,即便有可能无法和用户交互。
前台生存期:活动在onResume()方法和onPause()方法之间经历的就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,我们平时看到和接触最多的也就是这个状态下的活动。

4.活动被回收了问题

onSaveInstanceState()回调方法:我们可以通过这个方法来解决活动被回收时临时数据得不到保存的问题。

@Override
/* Bundle 类型的参数,使用 putString()方法保存字符串,使用 putInt()方法保存整型数据每个保存方法需要传入两个参数,第一个参数是键,用于后面从 Bundle中取值, 第二个参数是真正要保存的内容*/
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    String tempData = "Something you just typed";
    outState.putString("data_key", tempData);
}
//使用的 onCreate()方法其实也有一个 Bundle类型的参数,将数据取出即可。
@Override
protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
    Log.d(TAG, "onCreate");
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    if (savedInstanceState != null) {
        String tempData = savedInstanceState.getString("data_key");
        Log.d(TAG, tempData);
    }
    ……
}

四、活动的启动模式

启动模式一共有4种,分别是 standard、singleTop、singleTask 和 singleInstance。可以在 AndroidManifest.xml 中的 <activity> 标签中选择启动模式。

1、标准模式(standard):每启动一次Activity,就会创建一个新的Activity实例并置于栈顶。谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。
2、栈顶模式(singleTop):如果栈顶存在该activity的实例,则复用,不存在新建放入栈顶。
3、栈内模式(singleTask):如果栈内存在该activity的实例,会将该实例上边的activity全部出栈,将该实例置于栈顶,如果不存在,则创建。
4、单例模式(singleInstance):新开一个任务栈,该栈内只存放当前实例。