这一期我们来了解一些activity运行周期的问题、启动模式问题和intent的一些运用;
一个实例含有三种状态和七个事件,三个状态分别是运行、暂停和停止:
运行就是显示和可以操作的时候,有显示有焦点,暂停就是有显示没有焦点,就是黑了的时候,而停止是既没有显示也没有焦点,比如一个app跳转到另一个app;
七个事件有:
onCreate();
onStart();
onResume();
onPause();
onStop();
onDestroy();
onRestart();
分别是创建、开始、获取焦点、暂停、停止、销毁、重建;
一个app的启动需要进过前三个方法,而关闭就经过第四个和第五个方法;
1、了解了一些运行周期的方法和状态,我们开看看启动一个实例的模式:
一共含有四种:
注意我们的栈结构,先进后出,我们第一个打开的实例在栈底,显示的实例在栈顶
android:launchMode="standard"
android:launchMode="singleTop"
android:launchMode="singleTask"
android:launchMode="singleInstance"
android:launchMode="singleInstancePerTask"
第一种是默认的而且还是最普通的一种,就是我们打开一种实例就会在栈中创建一个,意思就是打开100个就会创建100个实例;
第二种就高级一点,我们实例位于栈顶的时候不会被创建,不过可以通过栈顶的app创建下面的实例;
第三种是单例模式,更加的高级,因为它一种实例就只能存在一个实例,如果打开已存在的实例,程序会将那个实例放到栈顶显示,而且清除掉在目标实例上面的实例;
第四种是就更高级了,它直接新建一个栈,可以说弥补了单任务模式的缺点(清除上面实例的缺点),同样也只会允许一种实例只有一个,如果存在就直接到新建的栈里面调用;
第五种是android12更新出来的,比较新,据官方文档说明,就是在第四种的基础上添加了两个属性:
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
那么就可以在第四种的基础上开启多个实例,这个实例通过intent指定,可以控制开启多个,毕竟新开了栈,这不就是第一种和第三种的集合体;
如果你们想要更改启动模式的话就找清单文件就可以了:
添加下面这个属性,我这里已经写了,其他的你们可以都试一试:
android:launchMode="singleInstancePerTask"
2、回想一下前面的知识,如果我们需要打开一个实例需要怎么做?
是不是使用Intent这个意图对象:
//1.2 使用方法一
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
//方法2
Intent intent1 = new Intent();
ComponentName componentName = new ComponentName(this,MainActivity.class);
intent1.setComponent(componentName);
startActivity(intent1);
//方法3
Intent intent2 = new Intent();
intent2.setClass(this,MainActivity.class);
startActivity(intent2);
这里我们可以使用三种方式来打开实例,也就是我们的activity;
一种直接在Intent带参数,第一个是上下文,第二个是目标activity,一种是不带参数通过创建组件对象,来将实例绑定到intent上,最后一种更是依赖于反射机制,直接设置类在intent上就可以开启了,当然我还是认为第一种好用有简单,不过大家看到其他的写法不要陌生,其实都是一个作用;
3、最后, 我们来学习隐式打开app,说道隐式和显示,其实都是指的是打开一个实例的方式,就像当我们指定一个人通过点名道姓和描述特征的区别,我们依据activity的某一个活动、数据等来模糊查询到对应的页面,那么就有可能会拿到多个实例,大家可以试一试,这里我就不介绍了,直接使用一个程序来演示一下如何打开安卓自带app:
布局代码:为了简单,我们直接使用线性布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="隐式启动安卓内置app"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="打开摄像头"
android:onClick="btn_cramen"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="打开浏览器"
android:onClick="btn_browse"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="打开联系人"
android:onClick="btn_contractperson"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_recipient"
android:hint="请输入收件人:"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/et_message"
android:hint="请输入信息:"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="发送短信"
android:onClick="btn_information"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="打开地图"
android:onClick="btn_map"/>
</LinearLayout>
布局非常简单,就是几个按钮加上两个编辑框,没啥技术含量,我们主要来学习一下打开实例的方式:
/1.2 开启相机
//一般我们都需要设置动作和环境
Intent intent = new Intent();
//都是固定写法
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
//1.3 打开浏览器百度网页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://baidu.com"));
startActivity(intent);
//1.4 打开联系人
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(ContactsContract.Contacts.CONTENT_URI);
startActivity(intent);
//1.5 发送信息
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
intent.addCategory("android.intent.category.DEFAULT");
//2.2 定义两个变量用于接收数据
String recipient = et_recipient.getText().toString();
String message = et_message.getText().toString();
intent.setData(Uri.parse("sms:"+recipient));
intent.putExtra("sms_body",message);
startActivity(intent);
//1.6 打开地图
Uri uri = Uri.parse("geo:38.9999,-77.9348");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
主要是很多都是固定的写法,还记得我们之前在组件里设置的监听函数吗,我们将上面的代码填入就可实现打开对应的app了:
package com.example.startactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
//1.1 创建好各个按钮监听和布局之后,我们开始编写intent来实现服务跳转
//因为我们在需要发送信息的时候需要获得组建的内容,所以我们先定义好两个组件
EditText et_recipient,et_message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//2.1 初始化变量
et_recipient = findViewById(R.id.et_recipient);
et_message = findViewById(R.id.et_message);
}
public void btn_cramen(View view) {
/* //1.2 使用方法一
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
//方法2
Intent intent1 = new Intent();
ComponentName componentName = new ComponentName(this,MainActivity.class);
intent1.setComponent(componentName);
startActivity(intent1);
//方法3
Intent intent2 = new Intent();
intent2.setClass(this,MainActivity.class);
startActivity(intent2);*/
//1.2 开启相机
//一般我们都需要设置动作和环境
Intent intent = new Intent();
//都是固定写法
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
public void btn_browse(View view) {
//1.3 打开浏览器百度网页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://baidu.com"));
startActivity(intent);
}
public void btn_contractperson(View view) {
//1.4 打开联系人
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(ContactsContract.Contacts.CONTENT_URI);
startActivity(intent);
}
public void btn_information(View view) {
//1.5 发送信息
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
intent.addCategory("android.intent.category.DEFAULT");
//2.2 定义两个变量用于接收数据
String recipient = et_recipient.getText().toString();
String message = et_message.getText().toString();
intent.setData(Uri.parse("sms:"+recipient));
intent.putExtra("sms_body",message);
startActivity(intent);
}
public void btn_map(View view) {
//1.6 打开地图
Uri uri = Uri.parse("geo:38.9999,-77.9348");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
}
}
至于发信息的时候创建两个变量获取到用户输入的数据进行发送相信大家都会,那么我们开始演示一下:
要特别注意,这一期大多数里理论知识,操作性不强,所以大家记住可以这么干和一些方法原理就可以了,这里的intent隐式操作都是固定的写法,只需要复制粘贴就可了,大概实现的效果就是这样,记住一定不要写错了;
好了,那么这一期就到这,快去试试吧。