96SEO 2026-02-23 15:18 20
向下一个Activity发送数据向上一个Activity返回数据

附加信息利用资源文件配置字符串利用元数据传递配置信息给应用页面注册快捷方式
onCreate创建活动。
把页面布局加载到内存进入了初始状态。
onStart开始活动。
把活动页面显示在屏幕上进入了就绪状态。
onResume恢复活动。
活动页面进入活跃状态能够与用户正常交互例如允许响应用户的点击动作、允许用户输入文字等等。
onDestroy销毁活动。
回收活动占用的系统资源把页面从内存中清除。
注如果一个Activity已经启动过了并且存在当前应用的Activity任务栈中启动模式为singleTasksingleInstance或singleTop此时已在任务栈顶端那么在此启动或回到这个Activity的时候不会创建新的实例也就是不会执行onCreate方法而是执行onNewIntent方法。
在该模式下每启动一个Activity就会在栈顶创建一个新的实例即启动的Activity会依照启动顺序被依次压入Task栈中。
实际开发中闹钟程序通常使用这种模式。
该模式会判断要启动的Activity实例是否位于栈顶如果位于栈顶则直接复用否则创建新的实例。
实际开发中浏览器的书签、应用支付跳转通常采用这种模式。
适合开启渠道多、多应用开启调用的Activity通过这种设置在一定条件下可以避免已经创建过的Activity被重复创建多数通过动态设置使用。
与singleTop模式类似只不过singleTop模式只是针对栈顶的元素而singleTask下如果task栈内存在目标Activity实例则将task内的对应Activity实例之上的所有Activity弹出栈并将对应Activity置于栈顶获得焦点。
应用场景
程序/浏览器主界面不希望主界面被创建多次而且在主界面退出的时候整个App是最好的效果。
耗费系统资源的Activity对于那些极其消耗系统资源的Activity我们可以考虑将其设为singleTask模式减少资源耗费。
在该模式下我们会为目标Activity创建一个新的Task栈将目标Activity放入新的Task并让目标Activity获得焦点。
新的Task有且只有这一个Activity实例。
如果已经创建过目标Activity实例则不会创建新的Task而是将以前创建过的Activity唤醒。
无论从哪个任务栈中启动该Activity该实例在整个系统中只有一个。
实际开发中来电界面通常使用这种模式。
打开配置文件AndroidManifest.xml给activity节点添加属性android:launchMode属性值填入standard表示采取标准模式当然不添加属性的话默认就是标准模式standard。
动态设置是通过Java代码设置的通过Intent动态设置Activity启动模式。
Intent类的启动标志说明Intent.FLAG_ACTIVITY_NEW_TASK开辟一个新的任务栈该值类似于launchMode“standard”不同之处在于如果原来不存在活动栈则FLAG_ACTIVITY_NEW_TASK会创建一个新栈Intent.FLAG_ACTIVITY_SINGLE_TOP当栈顶为待跳转的活动实例之时则重用栈顶的实例。
该值等同于launchMode“singleTop”Intent.FLAG_ACTIVITY_CLEAR_TOP当栈中存在待跳转的活动实例时则重新创建一个实例并清除原实例上方的所有实例。
该值与launchModesingleTask类似但singleTask采取onNewIntent方法启动原任务而FLAG_ACTIVITY_CLEAR_TOP采取先调用onDestroy再调用onCreate来创建新任务Intent.FLAG_ACTIVITY_NO_HISTORY该标志与launchMode“standard”情况类似但栈中不保存新启动的活动实例这样下次无论以何种方式再启动该实例也要走standard模式的完整流程即栈中不保存新启动的活动实例Intent.FLAG_ACTIVITY_CLEAR_TASK该标志非常暴力跳转到新页面时栈中的原有实例都被清空。
注意该标志需要结合FLAG_ACTIVITY_NEW_TASK使用即setFlags方法的参数为“Intent.FLAG_ACTIVITY_CLEAR_TASK
背景介绍假设活动A有个按钮点击该按钮会跳到活动B同时活动B也有个按钮点击按钮会跳到活动A从首页打开活动A之后就点击按钮在活动A与活动B之间轮流跳转。
此时活动页面的跳转流程为首页-活动A-活动B-活动A-活动B-活动A-活动B-…多次跳转之后想回到首页正常的话返回流程是这样的…活动B-活动A-活动B-活动A-活动B-活动A-首页每个箭头都代表按一次返回键可见要按下许多次返回键才能返回首页。
其实在活动A和活动B之间本不应该重复返回因为回来回去总是这两个页面是没有意义的。
照理说每个活动返回一次足矣同一个地方返回两次已经是多余的了再返回应当回到首页才是。
也就是说不管过去的时候怎么跳转回来的时候应该按照这个流程…活动B-活动A-首页或者…活动A-活动B-首页总之已经返回了的页面决不再返回第二次。
对于不允许重复返回的情况可以设置启动标志FLAG_ACTIVITY_CLEAR_TOP即使活动栈里面存在待跳转的活动实例也回重建该活动的实例并清除原实例上方的所有实例保证栈中最多只有该活动的唯一实例从而避免了无谓的重复返回。
于是活动A内部的跳转代码就改成了
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);当然活动B内部的跳转代码也要设置同样的启动标志
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);2登录成功后不再返回登录页面
背景介绍很多App第一次打开都要求用户登录登录成功再进入App首页如果这时按下返回键发现并没有回到上一个登录页面而是直接退出App了这又是什么缘故呢原来用户登录成功后App便记下用户的登录信息接下来默认该用户是登录状态自然不必重新输入用户名和密码。
既然默认用户已经登录哪里还需要回到登录页面不光登录页面登录之前的其他页面包括获取验证码、找回密码等页面都不应回去每次登录成功后整个App就焕然一新仿佛忘记有登录页面这回事。
设计思想对于回不去的登录页面情况可以设置启动标志FLAG_ACTIVITY_CLEAR_TASK该标志会清空当前活动栈里的所有实例。
不过全部清空之后意味着当前栈没法用了必须另外找个活动栈才行也就是同时设置启动标志FLAG_ACTIVITY_NEW_TASK该标志用于开辟新任务的活动栈这也就是为什么FLAG_ACTIVITY_CLEAR_TASK要配合着FLAG_ACTIVITY_NEW_TASK使用的原因如果没有设置FLAG_ACTIVITY_NEW_TASK则栈内对应的Activity销毁重新创建。
Intent(ActStartActivity.this,ActFinishActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
Intent是各个组件之间信息沟通的桥梁它用于Android组件之间的通信主要完成下面工作
标明本次通信请求从哪里来、到哪里去、要怎么走。
发起方携带本次通信需要的数据内容接收方从收到的意图中解析数据。
发起方若想判断接收方的处理结果意图就要负责让接收方传回应答的数据内容。
元素名称设置方法说明与用途ComponentsetComponent组件它指定意图的来源与目标ActionsetAction动作它指定意图的动作行为DatasetData即Uri它指定动作要操纵的数据路径CategoryaddCategory类别它指定意图的操作类别TypesetType数据类型它指定消息的数据类型ExtrasputExtras扩展信息它指定装载的包裹信息FlagssetFlags标志位它指定活动的启动标志
在构建一个意图对象时需要指定两个参数第一个参数表示跳转的来源页面即“来源Activity.this”第二个参数表示待跳转的页面即“目标Activity.class”具体的意图构建方式有如下3种
Intent(this,ActNextActivity.class);2调用意图对象的setClass方法指定
intent.setClass(this,ActNextActivity.class);3调用意图的setComponent方法指定
ComponentName(this,ActNextActivity.class);
intent.setComponent(component);隐式Intent
没有明确指定要跳转的目标活动只给出一个动作字符让系统自动匹配属于模糊匹配。
动作名称既可以通过setAction方法指定也可以通过构造函数Intent(String
Intent类的系统动作变量名系统动作的常量值说明ACTION_MAINandroid.intent.action.MAINApp启动时的入口ACTION_VIEWandroid.intent.action.VIEW向用户显示数据ACTION_SENDandroid.intent.action.SEND分享内容ACTION_CALLandroid.intent.action.CALL直接拨号ACTION_DIALandroid.intent.action.DIAL准备拨号ACTION_SENDTOandroid.intent.action.SENDTO发送短信ACTION_ANSWERandroid.intent.action.ANSWER接听电话
如果想要跳转到同一项目的不同模块module需要在目标模块的清单文件中做如下操作
activityandroid:name.CalculatorActivityandroid:exportedtrueintent-filteraction
android:nameandroid.intent.action.MAIN
android:nameandroid.intent.category.LAUNCHER
//intent-filterintent-filteraction
android:nameandroid.intent.action.WMY
android:nameandroid.intent.category.DEFAULT
/activity两个intent-filter表示CalculatorActivity有两种启动方式第一种是直接在桌面点图标来启动第二种是通过其他应用来启动。
if(v.getId()R.id.btn_my){Intent
Intent();intent.setAction(android.intent.action.WMY);intent.addCategory(Intent.CATEGORY_DEFAULT);startActivity(intent);
}注系统应用因为没有对应的Activity.class所以只能通过隐式Intent跳转。
系统应用就是找不到对应Activity的应用。
如上面常见的Intent类的系统动作所示以准备拨号和发短信为例
Intent();if(v.getId()R.id.btn_dial){//设置意图动作为准备拨号intent.setAction(Intent.ACTION_DIAL);//声明一个拨号的UriUri
Uri.parse(tel:phoneNo);intent.setData(uri);startActivity(intent);}else
if(v.getId()R.id.btn_sms){intent.setAction(Intent.ACTION_SENDTO);Uri
uri2Uri.parse(smsto:phoneNo);intent.setData(uri2);startActivity(intent);}整体代码如下
androidx.appcompat.app.AppCompatActivity;
{super.onCreate(savedInstanceState);setContentView(R.layout.activity_action_uri);findViewById(R.id.btn_dial).setOnClickListener(this);findViewById(R.id.btn_sms).setOnClickListener(this);findViewById(R.id.btn_my).setOnClickListener(this);}Overridepublic
Intent();if(v.getId()R.id.btn_dial){//设置意图动作为准备拨号intent.setAction(Intent.ACTION_DIAL);//声明一个拨号的UriUri
Uri.parse(tel:phoneNo);intent.setData(uri);startActivity(intent);}else
if(v.getId()R.id.btn_sms){intent.setAction(Intent.ACTION_SENDTO);Uri
uri2Uri.parse(smsto:phoneNo);intent.setData(uri2);startActivity(intent);}else
if(v.getId()R.id.btn_my){intent.setAction(android.intent.action.WMY);intent.addCategory(Intent.CATEGORY_DEFAULT);startActivity(intent);}}
xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticalTextViewandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:padding5dpandroid:text点击以下按钮将向号码12345发起请求/Buttonandroid:idid/btn_dialandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:text跳到拨号页面/Buttonandroid:idid/btn_smsandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:text跳到短信页面/Buttonandroid:idid/btn_myandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:text跳到我的页面/
/LinearLayout目标APP清单文件AndroidManifest.xml
xmlns:androidhttp://schemas.android.com/apk/res/androidapplicationandroid:allowBackuptrueandroid:iconmipmap/ic_launcherandroid:labelstring/app_nameandroid:roundIconmipmap/ic_launcher_roundandroid:supportsRtltrueandroid:***mestyle/Theme.Experiment01activityandroid:name.CalculatorActivityandroid:exportedtrueintent-filteraction
android:nameandroid.intent.action.MAIN
android:nameandroid.intent.category.LAUNCHER
//intent-filterintent-filteraction
android:nameandroid.intent.action.WMY
android:nameandroid.intent.category.DEFAULT
//intent-filter/activity/application
数据类型读方法写方法整型数getIntputInt浮点数getFloatputFloat双精度数getDoubleputDouble布尔值getBooleanputBoolean字符串getStringputString字符串数组getStringArrayputStringArray字符串列表getStringArrayListputStringArrayList可序列化序列getSerializableputSerializable
在代码中发送消息包裹调用意图对象的putExtras方法即可存入消息包裹
bundle.putString(request_time,DateUtil.getNowTime());//getNowTime是编写好的utils工具包中DateUtil工具库中用于获取当前事件的函数
bundle.putInt(request_count,1);
startActivity(intent)在代码中接收消息包裹调用意图对象的getExtras方法即可取出消息包裹
request_timebundle.getString(request_time);
request_countbundle.getInt(request_count);向上一个Activity返回数据
①上一个页面打包好请求数据调用ActivityResultLauncher方法执行跳转动作。
③下一个页面在返回上一个页面时打包应答数据并调用setResult方法返回数据包裹。
④上一个页面重写方法onActivityResult解析获得下一个页面的返回数据。
以请求方Activity与应答方Activity之间的数据传递为例详细描述该过程
androidx.activity.result.ActivityResult;
androidx.activity.result.ActivityResultCallback;
androidx.activity.result.ActivityResultLauncher;
androidx.activity.result.contract.ActivityResultContracts;
androidx.appcompat.app.AppCompatActivity;
com.example.myapplicationtwo.utils.DateUtil;
tv_request,tv_response;Overrideprotected
{super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_request);tv_requestfindViewById(R.id.tv_request);tv_request.setText(待发送的信息是:
mRequest);tv_responsefindViewById(R.id.tv_response);findViewById(R.id.btn_request).setOnClickListener(this);register
ActivityResultContracts.StartActivityForResult(),
result.getResultCode()RESULT_OK){Bundle
response_timebundle.getString(response_time);String
response_contentbundle.getString(response_content);String
descString.format(收到返回信息\n应答时间为%s\n应答内容为%s,response_time,response_content);//把返回信息的详情显示在文本视图上tv_response.setText(desc);}}});}Overridepublic
Intent(ActRequestActivity.this,ActResponseActivity.class);Bundle
Bundle();bundle.putString(request_time,
DateUtil.getNowTime());bundle.putString(request_content,mRequest);intent.putExtras(bundle);register.launch(intent);}
xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.ActRequestActivityandroid:orientationvertical!--上一个页面发送的内容--TextViewandroid:idid/tv_requestandroid:layout_widthmatch_parentandroid:layout_heightwrap_content/Buttonandroid:idid/btn_requestandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:gravitycenterandroid:text传送请求数据/!--下一个页面应答的内容--TextViewandroid:idid/tv_responseandroid:layout_widthmatch_parentandroid:layout_heightwrap_content/
androidx.appcompat.app.AppCompatActivity;
com.example.myapplicationtwo.utils.DateUtil;public
mResponse真的太没实力了;Overrideprotected
{super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_response);TextView
tv_requestfindViewById(R.id.tv_request);//获取从上一个页面传来的数据Bundle
bundlegetIntent().getExtras();String
request_timebundle.getString(request_time);String
request_contentbundle.getString(request_content);String
descString.format(收到请求信息\n请求时间为%s\n请求内容为%s,request_time,request_content);//把请求的信息显示在文本视图上面tv_request.setText(desc);findViewById(R.id.btn_response).setOnClickListener(this);TextView
tv_responsefindViewById(R.id.tv_response);tv_response.setText(待返回的消息为mResponse);}Overridepublic
Bundle();bundle.putString(response_time,DateUtil.getNowTime());bundle.putString(response_content,mResponse);intent.putExtras(bundle);//携带意图返回上一个页面
RESULT_OK表示处理成功setResult(Activity.RESULT_OK,intent);//强行结束当前页面
xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.ActResponseActivityandroid:orientationvertical!--上一个页面发送的内容--TextViewandroid:idid/tv_requestandroid:layout_widthmatch_parentandroid:layout_heightwrap_content/Buttonandroid:idid/btn_responseandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:gravitycenterandroid:text传送请求数据/!--下一个页面应答的内容--TextViewandroid:idid/tv_responseandroid:layout_widthmatch_parentandroid:layout_heightwrap_content/
nameidea真的是太没实力了/string//MainActivity.java
ideagetString(R.string.idea);利用元数据传递配置信息
调用getPackageManager方法获得当前应用的包管理器调用包管理器的getActivityInfo方法获得当前活动的信息对象活动信息对象的metaData是Bundle包裹类型调用包裹对象的getString即可获得指定名称的参数值
activityandroid:name.MainActivityandroid:exportedtrueintent-filteraction
android:nameandroid.intent.action.MAIN
android:nameandroid.intent.category.LAUNCHER
{//从应用包管理器中获取当前的活动信息ActivityInfo
pm.getActivityInfo(getComponentName(),PackageManager.GET_META_DATA);//获取活动附加的元数据信息Bundle
(PackageManager.NameNotFoundException
RuntimeException(e);}给应用页面注册快捷方式
元数据不仅能传递简单的字符串参数还能传送更加复杂的资源数据比如说支付宝的快捷方式菜单。
①首先在Project视图下的res目录下新建文件夹xml在xml文件夹中新建一个values
②在AndroidManifest.xml文件下的主活动中添加元数据使得长按会弹出之前xml文件下的shortcuts.xml菜单。
activityandroid:name.MainActivityandroid:exportedtrueintent-filteraction
android:nameandroid.intent.action.MAIN
android:nameandroid.intent.category.LAUNCHER
android:nameandroid.app.shortcuts
/activity③在shortcuts.xml文件中编写菜单列表内容。
其中shortcutShortLabel和shortcutLongtLabel中的内容通过string.xml字符串资源文件定义。
targetPackage为java文件下的文件名targetClass为捷径跳转的Activity名称这些待跳转的Activity因为是通过其他Activity启动的所以需要在清单文件中将它们的enabled属性设置为true。
xmlns:androidhttp://schemas.android.com/apk/res/androidshortcutandroid:shortcutIdfirstandroid:enabledtrueandroid:iconmipmap/ic_launcherandroid:shortcutShortLabelstring/first_shortandroid:shortcutLongLabelstring/first_longintentandroid:actionandroid.intent.action.VIEWandroid:targetPackagecom.example.myapplicationtwoandroid:targetClasscom.example.myapplicationtwo.ActStartActivity/categories
android:nameandroid.shortcut.conversation//shortcutshortcutandroid:shortcutIdsecondandroid:enabledtrueandroid:iconmipmap/ic_launcherandroid:shortcutShortLabelstring/second_shortandroid:shortcutLongLabelstring/second_longintentandroid:actionandroid.intent.action.VIEWandroid:targetPackagecom.example.myapplicationtwoandroid:targetClasscom.example.myapplicationtwo.ActRequestActivity/categories
android:nameandroid.shortcut.conversation//shortcutshortcutandroid:shortcutIdthirdandroid:enabledtrueandroid:iconmipmap/ic_launcherandroid:shortcutShortLabelstring/third_shortandroid:shortcutLongLabelstring/third_longintentandroid:actionandroid.intent.action.VIEWandroid:targetPackagecom.example.myapplicationtwoandroid:targetClasscom.example.myapplicationtwo.ActionUriActivity/categories
android:nameandroid.shortcut.conversation//shortcut
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback