四部分:

1、Activity生命周期

2、Activity任务栈

3、启动模式

4、scheme [skim] 跳转协议

Activity生命周期

Activity四种状态:running、paused、stopped、killed

Activity生命周期:

启动的时候:

点击回到桌面:

再次回到原Activity:

退出Activity;

进程优先级

前台、可见、服务、后台、空

Android任务栈

什么是任务栈、为什么需要任务栈

任务栈是以栈的形式,符合先进后出的原则。通过任务栈有序的管理每一个Activity

因为需要有启动模式,所以需要任务栈

启动模式

standard:不会考虑重用Activity,没启动一个Activity都会重新创建一个新的Activity

singleTop:栈顶复用。

singleTask:栈内复用。如果重用了Activity,会回调一个onNewIntent方法

singleInstance:独享栈模式

scheme跳转协议

Android中的自定义的URL Scheme是一种页面内跳转协议,也可以被称为URLRouter,就是通过类似打开网页的方式去通过路由打开一个Activity,而非直接通过显式Intent方式去进行跳转。

好处:

  • 降低耦合性:不需要知道具体要跳转哪个界面,只需要根据需求,按照约定好的URL路由协议发送Intent即可;
  • 更为安全:不显示Intent跳转,只要是符合协议的Intent都会有对应的Activity来匹配,避免了跳转到不该出现的页面;
  • 更为灵活: 有着更为广泛的应用场景,一下场景中都可以使用URL Scheme

作用:

  • 服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相应的页面
  • H5页面点击锚点,根据锚点具体跳转路径APP端跳转具体的页面
  • APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径跳转相关页
  • APP根据URL跳转到另外一个APP指定页面

URL Scheme协议格式

一个完整的完整的URL Scheme协议格式由scheme、host、port、path和query组成,其结构如下所示:

<scheme>://<host>:<port>/<path>?<query>

其中scheme既可以是Android中常见的协议,也可以是我们自定义的协议。Android中常见的协议包括content协议、http协议、file协议等,自定义协议可以使用自定义的字符串,当我们启动第三方的应用时候,多是使用自定义协议。

举个栗子:

xl://goods:8888/goodsDetail?goodsId=10011002

通过上面的路径 Scheme、Host、port、path、query全部包含:

xl,即为Scheme,代表该Scheme 协议名称

goods,即为Host,代表Scheme作用于哪个地址域

8888,即为port,代表该路径的端口号

goodsDetail,即为path, 代表Scheme指定的页面

goodsId,即为query,代表传递的参数

URL Scheme的使用方法

1)在AndroidManifest.xml中对<activity >标签增加<intent-filter>设置Scheme

<activity android:name=".MainActivity">
    <intent-filter> <!--正常启动-->
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter> <!--URL Scheme启动-->
        <!--必有项-->
        <action android:name="android.intent.action.VIEW"/>
        <!--如果希望该应用可以通过浏览器的连接启动,则添加该项-->
        <category android:name="android.intent.category.BROWSABLE"/>
        <!--表示该页面可以被隐式调用,必须加上该项-->
        <category android:name="android.intent.category.DEFAULT"/>
        <!--协议部分-->
        <data android:scheme="urlscheme"
            android:host="auth_activity">
    </intent-filter>
    <intent-filter>
        <action   android:name="emms.intent.action.check_authorization"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="emms.intent.category.authorization"/>
    </intent-filter>
</activity>

上面的设置中可以看到,MainActivity包含多个<intent-filter>设置,第一个是正常的启动,也就是在应用列表中启动;第二个是通过URL Scheme方式启动,其本身也是隐式Intent调用的一种,不同在于添加了<data>属性,定义了其接受URL Scheme协议格式为urlschemel://auth_activity

这里需要说明下,URL Scheme协议格式中,组成URI的这些属性在<data >标签中都是可选的 ,但存在如下的依赖关系:

2) 使用URL启动Activity

Uri data = Uri.parse("urlschemel://auth_activity");
  Intent intent = new Intent(Intent.ACTION_VIEW,data);
  //保证新启动的APP有单独的堆栈,如果希望新启动的APP和原有APP使用同一个堆栈则去掉该项
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  try {
    startActivityForResult(intent, RESULT_OK);
  } catch (Exception e) {
    e.printStackTrace();
    Toast.makeText(MainActivity.this, "没有匹配的APP,请下载安装",Toast.LENGTH_SHORT).show();
  }

网页中调用

<a href="urlschemel://auth_activity">打开新的应用</a>

在JS中调用

window.location = "urlschemel://auth_activity";

3)如何判断URL Scheme是否有效

boolean checkUrlScheme(Intent intent){
    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    return !activities.isEmpty();
}

将子APP在Home Launcher中隐藏

有时候需要把一些辅助性的、较为独立的APP在Home Launcher中隐藏起来,只允许一些特定的APP调用。这个时候,我们可以利用URL Scheme协议来做到这一点,设置AndroidManifest.xml中对<activity >标签如下

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <!--表示该页面可以被隐式调用,必须加上该项-->
        <category android:name="android.intent.category.DEFAULT"/>
        <!--协议部分-->
        <data android:scheme="urlscheme"
            android:host="auth_activity">
    </intent-filter>
</activity>

因为Home Launcher列出的应用图标要求必须有Activity同时满足

<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>

上面的配置中有多余的category和data限制存在,所以并不匹配,不会在Home Launcher出现,但是可以使用URL Scheme来启动。

Uri data = Uri.parse("urlschemel://auth_activity");
  Intent intent = new Intent(Intent.ACTION_MAIN,data);
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

这样就可以将一组APP设置一个统一的入口,然后根据实际需要在调用不同子APP,即所谓的APP业务组件化,URL Scheme在其中有着重要的作用。

results matching ""

    No results matching ""