启停活动页面
1、启动和停止
startActivity(new Intent(原页面.this,目标页面.this));
startActivity(new Intent(this,ActFinishActivity.class))
从当前页面回到上一个页面,相当于关闭当前页面,返回代码如下:
finish();
2、生命周期
第一次进入页面时:
onCreate
onStart
onResume
===========================================================
页面跳转到另外一个Activity时:
onPause
onStop
===========================================================
另外一个Activity再返回第一个Activity时:
onRestart
onStart
onResume
===========================================================
App返回到桌面:此时桌面应用成可见的了。桌面应用可以理解为一个Activity
onPause
onStop
onDestory
=======================================================
第一个activity快速跳转到第二个Activity,接着快速返回:
onPause,还没有来得及执行onPause
onResume,接着又重新渲染了
=======================================================
每个生命周期的状态:
1、onCreate:创建活动,把页面布局加载进内存,进入了初始化的状态。
2、onStart:开始活动,把互动页面显示在屏幕上,进入了就绪状态。
3、onResume:恢复活动,活动页面进入到活跃状态,能够与用户进行交互,例如,允许响应用户点击动作,允许用户输入文字等。
4、onPause:暂停活动,页面进入暂停状态,无法与用户正常交互。
5、onStop:停止活动。页面将不在屏幕上显示。
6、onDestory:销毁活动。回收活动占用的系统资源,把页面从内存中清除。
7、onRestart:重启活动。重新加载内存中的页面数据。
8、onNewIntent:重用已有的活动实例。【因为玩游戏,导致应用进入到后台运行,之后因为内存不足,进程被杀死,需要重新激活】
3、启动模式
App应用先后打开两个Activity,会有一个TaskStack。返回的时候出栈操作。
AndroidManifest.xml,给activity节点添加属性
启动标志取值-xml:
android:launchMode="standard" 默认值,表示开辟一个新的任务栈,已启动的activity会被依次压入到栈中。如果activity2跳转到activity2,会被压入栈顶两次。
android:launchMode="singleTop" 如果是栈顶,则重用栈顶的实例。activity2跳转到activity2,则会被压入栈顶一次。
android:launchMode="singleTask" 当栈中存在待跳转的活动实例时,则重新创建一个新实例,并清除原实例上方的所有实例。activity1->activity2->activity3,如果想要跳转到activity1,2和3会被弹出栈。
这就是相当于singleTask,如果没有这个,则会返回好多次才会返回到桌面。
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
登录成功之后,不会返回登录页面:
设置启动标志,跳转到新页面时,栈中的原有实例被清空,同时开辟新任务的活动栈。
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
对于回不去的登陆页面的情况,可以设置启动标志FLAG_ACTIVITY_CLEAR_TASK,该标志会清空当前活动栈里所有实例。不过全部清空之后,意味着当前栈没办法使用了,必须另外找个活动栈才行,也就是必须同时设置启动标志FLAG_ACTIVITY_NEW_TASK,该标志用于开辟新的任务栈。
启动标志取值-java:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//开辟一个新的任务栈
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//当栈顶为待跳转的活动实例之时,则重用栈顶的实例
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//当栈中存在待跳转的活动实例时,则重新创建一个新的实例,并清楚原实例上方的所有实例
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);//栈中不保存新启动的活动实例
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);//跳转到新页面时,栈中的原有实例都被清空
在活动之间传递消息
Intent的组成部分
元素名称 | 设置方法 | 说明与用途 |
Component | setComponent | 组件,指定意图的来源和目标 |
Action | setAction | 动作,指定意图的动作行为 |
Data | setData | 即Uri,指定动作要操纵的数据路径 |
Category | addCategory | 类别,指定意图的操作类别 |
Type | setType | 数据类型,它指定消息的数据类型 |
Extras | putExtras | 扩展信息,指定装载的包裹信息 |
Flags | setFlags | 标志位,它指定活动的启动标志 |
1、显示intent和隐式intent
显示Intent:
直接指定来源活动和目标活动,属于精确匹配。
在intent中的构造函数中指定
调用意图对象的setClass方法指定
调用意图对象的setComponent方法指定
Intent intent = new Intent(this,RelativeActivity.class);
Intent intent1 = new Intent();
intent1.setClass(this,RelativeActivity.class);
ComponentName componentName = new ComponentName(this, RelativeActivity.class);
intent1.setComponent(componentName);
startActivity(intent1);
startActivity(intent);
隐式Intent:
android.intent.action.MAIN | App启动时的入口 |
android.intent.action.VIEW | 向用户展示数据 |
android.intent.action.SEND | 分享内容 |
android.intent.action.CALL | 直接拨号 |
android.intent.action.DIAL | 准备拨号 |
android.intent.action.SENDTO | 发送短信 |
android.intent.action.ANSWER | 接听电话 |
String phoneNo = "17864152222";
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_DIAL);
Uri uri = Uri.parse("tel:"+phoneNo);
intent1.setData(uri);
startActivity(intent1);
APP之间跳转:
被暴露的app=要跳转的app,exported=true
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PSHDHX"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
app需要跳转的动作:只要action的名字对上,就能唤起app intent.setAction("android.intent.action.PSHDHX"); intent.addCategory(Intent.CATEGORY_DEFAULT); startActivity(intent);
2、向下一个Activity发送数据
intent使用Bundle对象存放传递的数据信息
Bundle对象操作各类数据类型的读写方法
字符串数组:getStringArray putStringArray
字符串列表:getStringArrayList putStringArrayList
可序列化结构:getSerializable putSerializable
Bundle bundle = new Bundle();
bundle.putString("requestTime",DateUtil.getNowTime());
bundle.putString("request_content","xxxxxxxxxxxxxxxxxx");
intent.putExtras(bundle);
startActivity(intent);
Bundle bundle1 = getIntent().getExtras();
String request_time = bundle1.getString("request_time");
3、向上一个Activity发送数据
处理好下一个页面的应答数据后,需要向上一个页面返回数据
1、上一个页面打包数据后,调用startActivityForResult方法执行此跳转动作
2、下一个页面解析请求数据,做出相应处理
3、下一个页面setResult方法返回数据包裹
5、上一个页面重写onActivityResult,解析下一个页面的返回数据
代码如下:
请求方代码
<?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"
tools:context=".RequestResActivity">
<TextView
android:id="@+id/tv_req"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_req"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="发送请求"/>
<TextView
android:id="@+id/res_in_req"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
package com.pshdhx.demo2;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.pshdhx.utils.DateUtil;
import java.util.Date;
public class RequestResActivity extends AppCompatActivity implements View.OnClickListener {
TextView tv_req;
TextView res_in_req;
Button btn_req;
private String req_text = "你睡了吗,我还没有睡";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request_res);
tv_req = findViewById(R.id.tv_req);
tv_req.setText("待发送的消息为:" + req_text);
btn_req = findViewById(R.id.btn_req);
btn_req.setOnClickListener(this);
res_in_req = findViewById(R.id.res_in_req);
}
@Override
public void onClick(View v) {
Intent intent = new Intent(this,ResponseReqActivity.class);
Bundle bundle = new Bundle();
bundle.putString("req_time:", DateUtil.getNowTime());
bundle.putString("req_content:", req_text);
intent.putExtras(bundle);
startActivityForResult(intent, 8888);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 8888){
if (resultCode == Activity.RESULT_OK) {
Bundle bundle = data.getExtras();
String res_time = bundle.getString("res_time");
String res_content = bundle.getString("res_content");
String desc = String.format("收到返回消息:\n应答时间为%s\n返回内容为%s", res_time, res_content);
res_in_req.setText(desc);
}
}
}
}
接收方代码:
<?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"
tools:context=".ResponseReqActivity">
<TextView
android:id="@+id/tv_res"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="返回数据"/>
<TextView
android:id="@+id/req_in_res"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
package com.pshdhx.demo2;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.pshdhx.utils.DateUtil;
import org.w3c.dom.Text;
public class ResponseReqActivity extends AppCompatActivity implements View.OnClickListener {
TextView tv_res;
Button btn_res;
TextView req_in_res;
private String res_text = "我还没有睡,我爸妈不在家";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_response_req);
tv_res = findViewById(R.id.tv_res);
btn_res = findViewById(R.id.btn_res);
req_in_res = findViewById(R.id.req_in_res);
req_in_res.setText("待响应的内容为:"+res_text);
btn_res.setOnClickListener(this);
Bundle bundle = getIntent().getExtras();
String req_time = bundle.getString("req_time:");
String req_content = bundle.getString("req_content:");
String desc = String.format("收到请求消息:\n请求时间为%s\n请求内容为%s", req_time, req_content);
tv_res.setText(desc);
}
@Override
public void onClick(View v) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("res_time", DateUtil.getNowTime());
bundle.putString("res_content", res_text);
intent.putExtras(bundle);
setResult(Activity.RESULT_OK,intent);
finish();
}
}
效果图:
踩坑的地方:
startActivityForResult(intent, 8888);
一开始我设置的是RESULT_OK,发现他的值是-1,然后onActivityResult这个方法无法接收到返回数据,不触发该方法的回调。
为活动补充附加信息
1、利用资源文件配置字符串
String appName = getString(R.string.app_name);
2、利用元数据传递配置信息
调用getPackageManager方法获取当前应用的包管理器
调用包管理器的getActivityInfo方法获得当前活动的信息对象
活动信息对象的metaData是Bundle包裹类型,调用包裹对象的getString即可获得指定名称的参数值。
PackageManager packageManager = getPackageManager();
try {
ActivityInfo activityInfo = packageManager.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
Bundle bundle = activityInfo.metaData;
String weather = bundle.getString("weather");
Toast.makeText(MetaDataActivity.this,weather,Toast.LENGTH_SHORT).show();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
3、给应用界面注册快捷方式
比如,在桌面,长按支付宝,会出现扫一扫,付钱之类的快捷方式,这是android7.0之后才有的功能。
代码:
<activity android:name=".shortCutActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- <meta-data-->
<!-- android:name="weather"-->
<!-- android:value="sunny" />-->
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
res/xml/shortcuts.xml
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="first"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:shortcutLongLabel="@string/first_long"
android:shortcutShortLabel="@string/first_short">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.pshdhx.demo2"
android:targetClass="com.pshdhx.demo2.RequestResActivity"
/>
<categories android:name="android.shortcut.conversation" />
</shortcut>
</shortcuts>
<resources>
<string name="app_name">安卓学习</string>
<string name="first_short">first</string>
<string name="first_long">启停活动</string>
</resources>