Android默认启动器原理

Android默认启动器原理Android 默认启动器原理一 描述 在 Android 中默认启动器 即能列出设备上的其他应用

大家好,欢迎来到IT知识分享网。

Android默认启动器原理

一. 描述:


二. 实现过程:

  1. 创建一个隐式intent并从PackageManager那里获取匹配他的所有activity,然后向PackageManager查询activity总数:
Intent startupIntent=new Intent(Intent.ACTION_MAIN); startupIntent.addCategory(Intent.CATEGORY_LAUNCHER); PackageManager pm=getActivity().getPackageManager(); List<ResolveInfo> activities=pm.queryIntentActivities(startupIntent,0); Log.i(TAG,“手机上一共有 ”+activities.size()+"个应用"); 

  定义了MAIN/LAUNCHER intent过滤器的activity是应用的主要入口点。 它只负责做好作为应用主要入口点要处理的工作,通常不关心自己是否为默认的主要入口点,所以可以不包含CATEGORY_DEFAULT类别。
  因为MAIN/LAUNCHER intent过滤器并不一定包含CATEGORY_DEAFULT类别,因此不能保证可以与startActivity()方法发送的隐式intent匹配。转而使用intent直接向PackageManager查询带有MAIN/LAUNCHER intent过滤器的activity。

  对比使用隐式intent发送文字等,先创建隐士intent,再将其封装在选择器intent中,最后调用startActivity(intent)方法发送给操作系统:

  1. 在视图中展示查询到的activity标签:
    activity标签是用户可以识别的展示名称。查询到的acitivity都是启动acitivity,那么标签名通常也就是应用名。在PackageManager返回的ResolveInfo对象中,可以获取activity标签和其他的一些元数据。
  2. 对activity标签排序:
    使用ResolveInfo,loadLabel(PackageManager)方法,对ResolveInfo对象中的activity标签按首字母排序。
Collections.sort(activities,new Comparator<ResolveInfo>(){ public int compare(ResolveInfo a,ResolveInfo b){ return String.CASE_INSENSITIVE_ORDER.compare( a.loadLabel(pm).toString(), b.loadLabel(pm).toString()); } }); 
  1. 启动目标Activity:
      在运行时创建显式Intent,点击任一应用label,启动对应的activity要创建启动acitivty的显式intent,需要从ResolveInfo对象中获取activity的包名和类名。这些信息从ResolveInfo对象的ActivityInfo中获取。
    (注:了解ResolveInfo类,去 developer.android.com 官网去查阅)
    可以注册列表监听器,并使用ActivityInfo对象中的数据信息,创建一个显式intent并启动目标Activity:


ActivityInfo activityInfo=mResolveInfo.activityInfo; Intent i=new Intent(Intent.ACTION_MAIN) .setClassName(activityInfo.applicationInfo.packageName,activityInfo.name); startActivity(i); 

public Intent setClassName(String packageName,String className)

这是使用包名和类名创建显式intent时采用的Intent方法。这个平常创建显式intent的方式有点不同。通常,我们使用的是接受Context和Class对象的Intent构造方法:

public Intent(Context packageContext,Class<?>cls)

该构造方法使用传入的参数来获取Intent需要的ComponentName。ComponentName由包名和类名共同组成。传入Activity和Class创建Intent时,构造方法会通过Activity类自行确定全路径包名。也可自己通过包名和类名创建ComponentName,然后使用下面的 Intent方法创建显式Intent:

public Intent setComponent(ComponentName component) 

但是,setClassName()能够自动创建组件名。用它可以简化代码。

经过这几个步骤,就可以使用自定义的APP来启动你本机上的一些应用了。

最终结果:

在这里插入图片描述


三. 分离任务:

在app运行时,android使用任务来跟踪用户的状态。通过android默认启动应用打开的应用都有自己的任务。然而,这不适用于上面代码中创建的APP。即上述代码中创建的APP打开手机上的应用,然后按任务列表按钮,会发现只有android默认启动应用app的任务图标,而没有目标app的任务,而目标任务的视图却在android默认启动应用app的任务视图中。要想让目标app独立出自己的任务,需要明白:任务和回退栈

  • 任务和回退栈:
    任务是一个acitivty栈。栈底部的activity通常称为基activity。栈顶的activitiy是用户能够看到的。如果按后退键,栈顶的activiity会弹出栈外。如果用户看到的是基activity,按后退键,系统就会回到主屏幕。
    默认情况下,新的activity都是在当前任务中启动的。在android默认启动应用app中,无论何时启动新activity,它都会被添加到当前任务中。即使要启动的activity不属于本应用(在本app中打开第三方app),它也同样在当前任务中启动。
    在当前任务中启动activity的好处是:用户可以在任务内而不是在应用层级间导航返回。


  • 在任务间切换:
    在不影响各个任务状态的情况下,最近任务列表按钮(home键旁边的那个建)可以让我们在任务间切换。例如在加入联系人信息,然后转到抖音去看视频,这时就启动了2个任务。如果再回到联系人应用,我们在2个任务中所处的操作状态都会被保存下来。
  • 启动新任务:
    有时需要在当前任务中启动activity,有时又需要在新任务中启动activity。
    当前,android默认启动应用app启动的任何activity都会被添加到本应用的任务中。即打开最近任务列表按钮可以看到目标actiivty视图显示在本应用的视图中。
    现在, 我们需要在新任务中启动activity,如下图效果:
    在这里插入图片描述



Intent i=new Intent(xxx) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

然后运行程序,就能看见如上面效果图的显示效果了。目标应用处于了一个单独的任务中,如果从启动器应用中再次启动目标应用,也不会创建第二个相同的目标任务。FLAG_ACTIVITY_NEW_TASK标志控制每个activity仅仅创建一个任务。


四. 使用自定义的APP应用作为设备主屏幕:

试想你是用户,你会愿意专门下载一个APP来每次启动你手机上的应用吗?肯定不会啊,浪费内存。

  • 步骤:
    打开项目的AndroidManifest,xml,向Intent主过滤器中添加节点定义:
    注:一个intent-filter中只允许存在一个action,但允许存在多个category.

<intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.HOME"/> <category android.name="android.intent.category.DEFAULT"/> </intent-filter> 

添加完HOME和DEAFULT类别定义后,应用的activity会成为可选的主界面。按主屏幕键会弹出对话框,本应用成了主界面的可选项。

  清除该设置,可以在手机上的”设置-》应用-》本应用名-》清除默认按钮“。


补充:

光有每个应用activity的名字还不够,我们还可以使用ResolveInfo.loadIcon() 来为每个应用加载显示图标


扩展:关于WPS软件中的并发打开(多开效果)

  • 效果图:
    在这里插入图片描述
  • 原理:并发文档。
    所打开的多个wps中的pdf文档,这些文档不会被添加到WPS应用任务中,而是添加到它自己的独立任务中。对于以android.intent.action.SEND或者action.intent.action.SEND_MULTIPLE启动的actiivty,隐式intent选择器会创建独立的新任务。
    这种现象就是并发文档(concurrent document)。有了并发文档就可以 为运行的应用动态创建任意数目的任务。
    比如WPS可以同时打开并编辑多份文档,这些文档编辑activity都处在独立的任务中。


要i想应用启动多个任务,可采用如下2种方式:

  1. 给Intent加上Intent.FLAG_ACTIVITY_NEW_DOCUMENT标签,再调用startActivity()方法。
  2. 在清单文件中,为activity设置如下documentLaunchMode:
<activity android:name="xxxx" android:documentLaunchMode="intoExisting"/> 

使用上述的方法后,一份文档只对应一个任务。如果发送带有和已存在任务相同数据的intent,系统就不会再创建新任务。如果无论如何都i想创建新任务,就给intent同时加上Intent.FLAG_ACTIVITY_NEW_DOCUMENT、Intent,FLAG_ACITVITY_MULTIPLE_TASK标签,或者在清单文件中的documentLaunchMode的属性值改为always.

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/128608.html

(0)
上一篇 2025-08-30 15:45
下一篇 2025-08-30 16:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信