导航:首页 > 操作系统 > 淘宝androidscheme

淘宝androidscheme

发布时间:2022-10-09 16:01:02

A. 在一个Activity的java程序中,具体看问题描述

1、Intent

Intent是各个组件之间交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,而且还能在各组件之间传递数据。Intent一般可用于启动Activity、启动Service、发送广播等场景。

Intent大致可分为2中:

1、显示Intent

2、隐式Intent

1.1、显示Intent打开Activity

fun openActivity(){
val intent = Intent(this, KotlinFirstActivity::class.java)

intent.putExtra("param", "testParams")

startActivity(intent)

}

注意:KotlinFirstActivity::class.java就相当于Java中的KotlinFirstActivity.class。

1.2、隐式Intent打开程序内的Activity

相比于显示Intent,隐式Intent并不指明启动那个Activity而是指定了一系列的action和category,然后交由系统去分析找到合适的Activity并打开。

什么是合适的Activity,其实就是和隐式Intent中指定的action和category完全匹配的Activity,而action和category我们可以在AdnroidManifest中指定。

在标签中配置了action和category,只有和隐式Intent中的action和category完全匹配才能正常的打开该页面。

val intent = Intent("com.example.abu.alertdialogdemo.ACTION_START")

startActivity(intent)

不是说action和category要完全匹配才能打开页面吗?这是因为android.intent.category.DEFAULT是一种默认的category,在调用startActivity()时会自动将这个category添加到Intent中。所以在Manifest中一定不要忘记配置这个默认的category:android.intent.category.DEFAULT,否则会报错。

还有一点需要注意:Intent中只能添加一个action,但是可以添加多个category。

1.3、隐式Intent打开程序外的Activity

比如我们要打开系统的浏览器

fun openWeb(view: View) {
val intent = Intent(Intent.ACTION_VIEW)

intent.data = Uri.parse("https://www..com")

startActivity(intent)

}

Intent.ACTION_VIEW是系统内置的动作,然后将https://www..com通过Uri.parse()转换成Uri对象,传递给intent.setData(Uri uri)函数。Kotlin中intent.data=Uri.parse("https://www..com")就相当于Java中的intent.setData(Uri.parse("https://www..com")),这是Kotlin中的语法糖。

与此对应在标签中配置一个标签,用于更精确的指定当前Activity能够相应的数据。标签中主要可以配置一下内容:

1、android:scheme:用于指定数据的协议部分,如https

2、android:host:用于指定数据的主机名部分,如www..com

3、android:port:用于指定数据的端口,一般紧随主机名后

4、android:path:用于指定数据的路径

5、android:mimeType:用于指定支持的数据类型

只有当标签中指定的内容和Intent中携带的data完全一致时,当前Activity才能响应该Intent。下面我们通过设置data,让它也能响应打开网页的Intent。

我们在ThirdActivity的中配置当前Activity能够响应的action是Intent.ACTION_VIEW的常量值,而category指定了默认的category值,另外在标签data中我们通过android:scheme="https"指定了数据的协议必须是https。另外由于AndroidStudio认为能够响应ACTION_VIEW的Activity都应该加上BROWSABLE的category,否则会报出警告。加上BROWSABLE的category是为了实现deep link 功能和目前学习无关,所以我们在intent-filter标签上添加tools:ignore="AppLinkUrlError"忽略警告。

然后我们就能通过隐式Intent的方法打开ThirdActivity了,代码如下:

val intent= Intent(Intent.ACTION_VIEW)

intent.data=Uri.parse("https:")

startActivity(intent)

除了指定android:scheme为https我们也能随意指定它的值,只需要保证AndroidManifest中设置的值和Intent中设置的data相对应即可。

2、Activity的生命周期

Activity类中定义了7个回调方法,覆盖了Activity声明周期的每一个环节。

1、onCreate(): 在Activity第一次创建时调用

2、onStart():在Activity可见但是没有焦点时调用

3、onResume():在Activity可见并且有焦点时调用

4、onPause():这个方法会在准备启动或者恢复另一个Activity时调用,我们通常在该方法中释放消耗CPU的资源或者保存数据,但在该方法内不能做耗时操作,否则影响另一个另一个Activity的启动或恢复。

5、onStop():在Activity不可见时调用,它和onPause主要区别就是:onPause在失去焦点时会调用但是依然可见,而onStop是完全不可见。

6、onDestory():在Activity被销毁前调用

7、onRestart():在Activity由不在栈顶到再次回到栈顶并且可见时调用。

为了更好的理解Activity的生命周期,看下图

Activity生命周期.png

3、体验Activity的生命周期

下面我们通过实例更直观的看下Activity的生命周期过程。

1、打开FirstActivity,生命周期过程如下

FirstActivity onCreate

FirstActivity onStart

FirstActivity onResume

2、在FirstActivity中打开SecondActivity,生命周期过程如下

FirstActivity onPause

SecondActivity onCreate

SecondActivity onStart

SecondActivity onResume

FirstActivity onStop

可以看到在打开SecondActivity时FirstActivity的onPause会执行,所以在onPause中是不能做耗时操作的,否则会影响SecondActivity的打开。

3、按返回键回到FirstActivity,生命周期过程如下

SecondActivity onPause

FirstActivity onRestart

FirstActivity onStart

FirstActivity onResume

SecondActivity onStop

SecondActivity onDestroy

可以看到在返回FirstActivity时会调用SecondActivity的onPause,如果SecondActivity的onPause中做了耗时操作的话,那么也会影响Activity的返回。而且当FirstActivity再次回到栈顶时会调用其onRestart,此时并不会执行onCreate因为FirstActivity并没有销毁。

4、Activity被回收了时的生命周期

现在描述一种场景:打开ActivityA,然后在ActivityA的页面中打开ActivityB,此时ActivityA不在栈顶了如果内存不足可能会被回收,此时从ActivityB再回到ActivityA,下面描述下整个过程的生命周期。

1、打开ActivityA,执行的生命周期

ActivityA onCreate

ActivityA onStart

ActivityA onResume

2、打开ActivityB执行的生命周期

ActivityA onPause

ActivityB onCreate

ActivityB onStart

ActivityB onResume

ActivityA onStop

3、此时因内存不足,导致ActivityA被回收了,并返回ActivityA

ActivityA onDestory

ActivityB onPause

ActivityA onCreate

ActivityA onStart

ActivityA onResume

ActivityB onStop

从上面可以看出在ActivityA被回收后再次回到ActivityA时不再调用ActivityA的onRestart了,而是调用了ActivityA的onCreate,因为ActivityA已经被销毁了。

5、Activity被销毁,其中的临时数据怎么办

ActivityA被销毁了,这也就说明其中的临时数据也会丢失了,比如ActivityA中有一个EditText,我们在其中输入了一段文字,然后启动ActivityB,此时由于内存紧张处于停止状态的ActivityA被回收了,返回到ActivityA你会发现EditText中输入的文字不见了,因为ActivityA重新创建了。

为此Activity提供了onSaveInstanceState方法,该方法能确保在被回收之前被调用,我们就能在onSaveInstanceState方法中进行临时数据的保存,然后我们可以在onCreate(savedInstanceState: Bundle?)中利用savedInstanceState进行数据的恢复。Activity被回收重新创建时onCreate(savedInstanceState: Bundle?)中的savedInstanceState不再为null否则为null,其中带有在savedInstanceState中保存的所有数据。

具体代码如下:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

Log.e("tag", "$tag onCreate")

//恢复数据

val tempData = savedInstanceState?.getString("data") ?: ""

et.setText(tempData)

}

//保存数据

override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)

Log.e("tag", "$tag onSaveInstanceState")

val tempData = et.text.toString().trim()

outState?.putString("data", tempData)

}

6、onSaveInstanceState()调用时机

1、用户按下HOME键

2、长按HOME键进入其他程序

3、按下电源键关闭屏幕

4、从ActivityA跳转到一个新的Activity

5、屏幕方向切换时,如从竖屏变成横屏

总而言之,onSaveInstanceState()是在你的Activity有可能在未经允许的情况下被回收时调用,Activity被销毁之前onSaveInstanceState()肯定会被触发,我们可以onSaveInstanceState()中保存临时数据,持久化的数据可以在onPause()中保存。

另外,虽然屏幕方向切换时,会造成Activity的重建会调用onSaveInstanceState(),但是不建议使用onSaveInstanceState()进行数据的保存,我们可以禁止屏幕的旋转或禁止屏幕旋转时Activity的重建。

禁止屏幕旋转

可以在Mainifest中设置屏幕固定为竖屏

android:screenOrieritation="portrait"

禁止屏幕旋转时Activity的重建

android:configChanges="orientation丨keyboardHidden丨screenSize"

7、Activity的启动模式

启动模式分为4种:

1、standard

2、singleTop

3、singleTask

4、singleInstance

我们可以在Manifest中通过android:launchMode指定启动模式。

7.1、standard模式

如果不显示指定启动模式,那么Activity的启动模式就是standard,在该模式下不管Activity栈中有无该Activity,均会创建一个新的Activity并入栈,并处于栈顶的位置。

7.2、singleTop模式

1、要启动的Activity位于栈顶

在启动一个ActivityA时,如果栈顶的Activity就是ActivityA,那么就不会重新创建ActivityA,而是直接使用,此时并不会调用ActivityA的onCreate(),因为并没有重新创建Activity,ActivityA的生命周期如下:

ActivityA onPause

ActivityA onNewIntent

ActivityA onResume

可以看到调用了onNewIntent(intent: Intent?),我们可以在onNewIntent(intent: Intent?)中通过intent来获取新传递过来的数据,因为此时数据可能已经发生了变化。

2、要启动的Activity不在栈顶

虽然我们指定了ActivityA的启动模式为singleTop,但是如果ActivityA在栈中但是不在栈顶的话,那么此时启动ActivityA的话会重新创建一个新的ActivityA并入栈,此时栈中就有2个ActivityA的实例了。

7.3、singleTask模式

如果准备启动的ActivityA的启动模式为singleTask的话,那么会先从栈中查找是否存在ActivityA的实例:

场景一、如果存在则将ActivityA之上的Activity都出栈,并调用ActivityA的onNewIntent()。

场景二、如果ActivityA位于栈顶,则直接使用并调用onNewInent(),此时和singleTop一样。

场景三、 如果栈中不存在ActivityA的实例则会创建一个新的Activity并入栈。

场景一:ActivityA启动ActivityB,然后启动ActivityA,此时生命周期过程:

ActivityB onPause

ActivityA onRestart

ActivityA onStart

ActivityA onNewIntent

ActivityA onResume

ActivityB onStop

ActivityB onDestroy

此时ActivityA不在栈顶,ActivityA之上有ActivityB,所以在启动ActivityA时ActivityA之上的ActivityB会出栈,ActivityA将置于栈顶,所以ActivityA的onRestart和ActivityB的onDestory会执行。

场景二:ActivityA启动ActivityA,此时生命周期过程:

ActivityA onPause

ActivityA onNewIntent

ActivityA onResume

此时ActivityA位于栈顶,此时singleTask和singleTop作用一样,都是直接使用ActivityA,并且会调用ActivityA的onPause、onNewIntent、onResume。

场景三:ActivityA启动ActivityB,此时生命周期过程:

ActivityA onCreate

ActivityA onStart

ActivityA onResume

7.4、singleInstance模式

不同于另外3个模式,指定singleInstance模式的Activity会启动一个新的返回栈来管理这个Activity(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈),这么做的意义是什么?

想象一个场景:如果我们程序内的一个Activity是允许其他程序访问的,如果想实现其他程序和我们程序能共享这个Activity实例,该怎么实现呢?使用前面3中模式是无法做到的,因为每个应用程序都有自己的返回栈,同一个Activity在不同返回栈中肯定都创建了新的实例,而使用singleInstance就可以解决这个问题。在这种模式下,会有一个单独的返回栈来管理这个Activity,无论哪个应用程序来访问这个Activity,都在同一个返回栈中,也就解决了共享Activity实例的问题。

为了更好的理解下面我们实战一下:

1、将ActivityB的启动模式修改为singleInstance

android:name=".ActivityB"

android:launchMode="singleInstance" />

2、在ActivityA、ActivityB、ActivityC的onCreate中打印taskId

##ActivityA

val tag = javaClass.simpleName

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

Log.e("TAG", "$tag taskId=$taskId")

}

##ActivityB

val tag = javaClass.simpleName

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(activity_second)

Log.e("TAG", "$tag taskId=$taskId")

}

##ActivityC

val tag = javaClass.simpleName

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(activity_c)

Log.e("TAG", "$tag taskId=$taskId")

}

在Kotlin中javaClass是当前实例的Class对象,相当于Java的getClass().

在Kotlin中ActivityB::class.java是获取ActivityB类的Class对象,相当于Java中的ActivityB.class。

3、启动ActivityA->启动ActivityB->启动ActivityC,taskId打印结果如下:

ActivityA taskId=4163

ActivityB taskId=4164

ActivityC taskId=4163

可以看到ActivityB的taskId是不同于ActivityA 和ActivityC的,这也说明了ActivityB 是在一个单独的栈中的,并且返回栈中只有这一个Activity。

4、在ActivityC中按返回键,返回到ActivityA,再按返回键返回到ActivityB,这是为什么呢?其实很好理解:ActivityA 和ActivityC 在同一个返回栈中,在ActivityC 中按返回键ActivityC 出栈,此时ActivityA就位于栈顶了,ActivityA就展示在界面上了,在ActivityA中再按返回键,这是当前的返回栈已经空了,于是就展示了另一个返回栈栈顶的ActivityB了。
————————————————
版权声明:本文为CSDN博主“保瓶儿”的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_31211457/article/details/114052641

B. 为什么支付宝付完款自动跳转到了淘宝 怎样关闭

【PConline资讯】今天有苹果iPhone用户反馈,如果在支付宝内尝试打开淘宝APP,会自动跳转到另外一个APP,仿佛被“劫持”了一样。

支付宝官方回应称,经过支付宝和淘宝技术团队排查发现,这个APP使用了和淘宝同样的URLScheme(类似URL网址),从而干扰iOS系统判断,出现跳转错误。



只有安装了这个APP的iPhone手机才会出现这一跳转错误问题,Android不受影响。

用户可以手动关闭这个被打开的APP,将其卸载,就能恢复正常。

支付宝表示,已经与该APP紧急沟通,希望其不要再使用这样的途径来引导用户跳转。

事实上,这一问题的根源在于苹果iOS系统不完善,允许不同的APP设置同一个URLScheme,事实上很多APP都曾受到困扰。

C. 自定义URL Scheme启动应用

在使用手机时,经常会出现一种场景,当点击某个链接时,会启动已经安装的某个应用来完成接下来的流程。比如当点击网页中一个淘宝的购物链接时,如果手机安装了淘宝客户端,便会导致客户端被唤醒。

iOS中可以通过自定义URL Scheme机制来实现这种跳转,从而带来更好的用户体验。

URL Scheme跳转机制非常简单,只需要修改info.plist增加一个键值即可。

按图中的方式创建URL Scheme,在属性字典中添加了一个URL types键值对,设置内容可以参考图中的设置方式。现在以xml文件方式打开info.plist文件,可以看出对应的信息如下:

完成上述操作后,在模拟器或真机上启动应用,然后打开safari,在地址栏中输入 usd:// 或 urlsd:// ,系统会弹出提示框,提示是否跳转到应用,如果点击确认,便会跳到自己的应用。

只要URL的scheme与应用中定义的scheme相同,便可以从外部(比如safari)打开应用。当应用打开时,该应用的方法 - application:handleOpenURL: 会被调用,而在该方法中能够获取到完整的URL,因此外部应用能够通过URL向被打开的应用传递参数。

下图为一个http协议的URL,其scheme为http。

比如本例中在浏览器中输入 usd://scheme.demo/dir/redirect?sku=123&lang=en ,此时应用会被打开。在方法 - application:handleOpenURL: 中设置断点,可以观察到如下信息:

此时通过解析 query 字段,应用便可获取外部应用传入的参数。

D. android用什么样的方式可以在用户点击链接的时候自动打开app

网页中插入链接或者跳转至链接:
<a href="m://my.com/">打开app</a>

在AndroidManifest的清单文件里的intent-filte中加入如下元素:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="my.com"
android:scheme="m" />
</intent-filter>

E. URL scheme启动Android应用,原生Android浏览器解析不正确

1、自定义URL Scheme:
创建一个activity并加上一个<intent-filter>(如果该activity是包含其他<intent-filter>,则需新建一个<intenf-filter>,不能在原有filter上添加),内容为:
<action android:name="android.intent.action.VIEW"/><!-- 若删除,使用startActivity启动android.content.ActivityNotFoundException,使用HTMLViewer启动找不到网页-->
<category android:name="android.intent.category.BROWSABLE"/><!-- 若删除,使用startActivity启动ok,使用HTMLViewer启动找不到网页 -->
<category android:name="android.intent.category.DEFAULT"/><!-- 若删除,使用startActivity启动android.content.ActivityNotFoundException,使用HTMLViewer启动找不到网页-->

<data android:scheme="myapp"/><!-- scheme的值可自定义 -->
2、通过URL Scheme启动Android应用
方式一:通过代码访问:Intent intent = new Intent();

/**parse的参数值说明如下
* 只写myapp,启动android.content.ActivityNotFoundException
* 写myapp://12,成功
* 写myapp://da?sd=ad,成功
*/
intent.setData(Uri.parse("myapp://12"));
startActivity(intent);

方式二:通过网页访问:
/**href的值说明如下
* 只写myapp,找不到网页
* 写myapp://12,成功
* 写myapp://da?sd=ad,成功
*/

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>通过URL Scheme启动Android应用</title>
</head>
<body>
<form>
<a href="myapp://12">启动</a>
</form>
</body>

</html>
创建完成后发送到手机,再点击html选择使用HTMLViewer打开,再点击链接即可启动应用。
3、总结:第二种方式实现有点繁琐,最好的实现方式是直接在浏览器中输入url以启动应用。在网上搜索找到应如下操作:在浏览器的搜索栏输入如下url:content://com.android.htmlfileprovider/storage/emulated/0/myapp://12,经测试无法成功。不知道是哪里的问题,还请知道的指点一二。

F. 如何启动 天猫客户端 android开发

在项目中遇到了这样一个需求:让用户在手机应用中,点击一个天猫的商品链接(知道商品在PC浏览器里的地址),直接启动天猫的客户端并显示这个商品。以前曾经实现过类似的功能,不过那次是xx的商品,天猫和淘宝的客户端不同,参数也不一样,直接套的格式就不行了。不过,总体的思路还是类似的,就是使用iOS 的URL SCHEME机制。

阅读全文

与淘宝androidscheme相关的资料

热点内容
怎么把电脑里文件夹挪出来 浏览:693
java流程处理 浏览:683
ftp创建本地文件夹 浏览:659
腰椎第一节压缩 浏览:738
xp去掉加密属性 浏览:117
2345怎么压缩文件 浏览:982
迷你夺宝新算法 浏览:407
服务器如何防止木马控制 浏览:715
压缩空气用电磁阀 浏览:742
微信为什么不能设置加密认证 浏览:672
邓伦参加密室逃脱视频 浏览:391
音频压缩编码标准 浏览:300
常提到的app是表示什么 浏览:261
天津程序员传销 浏览:349
下班之后的程序员 浏览:73
检测支持ssl加密算法 浏览:344
衢州发布新闻什么APP 浏览:85
中国移动长沙dns服务器地址 浏览:252
wifi密码加密了怎么破解吗 浏览:599
linux命令cpu使用率 浏览:70