启停活动页面
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"><TextViewandroid:id="@+id/tv_req"android:layout_width="match_parent"android:layout_height="wrap_content"/><Buttonandroid:id="@+id/btn_req"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="发送请求"/><TextViewandroid: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 = "你睡了吗,我还没有睡";@Overrideprotected 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);}@Overridepublic 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);}@Overrideprotected 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"><TextViewandroid:id="@+id/tv_res"android:layout_width="match_parent"android:layout_height="wrap_content"/><Buttonandroid:id="@+id/btn_res"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="返回数据"/><TextViewandroid: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 = "我还没有睡,我爸妈不在家";@Overrideprotected 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);}@Overridepublic 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-dataandroid: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"><shortcutandroid:shortcutId="first"android:enabled="true"android:icon="@mipmap/ic_launcher"android:shortcutLongLabel="@string/first_long"android:shortcutShortLabel="@string/first_short"><intentandroid: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>