当前位置: 首页 > news >正文

做网站 人员做引流推广的平台600

做网站 人员,做引流推广的平台600,wordpress警告弹窗,什么网站做任务赚钱吗前言 很多应用开发人员,在日常开发过程中,经常会遇到一些需求,例如需要知道当前最上层的Activity是哪个,并结合这个Activity的名称来完成一些特定场景的需求。最简单的方法,是在创建Activity的时候将该Actvity存储到一…

前言

很多应用开发人员,在日常开发过程中,经常会遇到一些需求,例如需要知道当前最上层的Activity是哪个,并结合这个Activity的名称来完成一些特定场景的需求。最简单的方法,是在创建Activity的时候将该Actvity存储到一个集合中,而当Activity销毁的时候,再将该Activity从集合中移除,这种方案虽然能够获取自己应用当前最上层的Activity是那个,但却无法获取除了自己应用以外的其他场景。犹豫谷歌为系统开发提供了特定的API,作为系统开发人员,我们完全可以通过这些API实时获取当前最上层的Activity信息,并将这些信息同步给系统应用。本篇文章我们将会结合Android12的系统源码,来探讨一下如何通过系统内部API实时获取当前系统最上层的Activity的信息,以及如何实时监听当前系统Activity栈信息的变化。

一、获取最上层的根任务信息

1、根任务是指包含一个或多个 Activity 的任务,并且没有父任务,根任务通常是由用户启动的应用程序或系统应用程序的主要任务。
在 Android 12 中,我们可以通过以下代码获取最上层的根任务信息。

IActivityManager ams = ActivityManager.getService(); //获取ActivityManagerService服务对象
List<ActivityManager.RunningTaskInfo> runningTasks = mAm.getTasks(1);;//调用getAllRootTaskInfos方法

首先调用ActivityManager的getService方法获取ActivityManagerService服务对象,然后调用该服务对象的getTasks(int maxNum) 方法,该方法会返回一个指定数量包含所有根任务信息的列表,每个根任务都有其任务 ID、根 Activity 的信息以及与之关联的其他活动堆栈。

2、来看下和RunningTaskInfo类相关的代码。

base/core/java/android/app/ActivityManager.java

public class ActivityManager {public static class RunningTaskInfo extends TaskInfo implements Parcelable {/*** 当前任务的唯一标识id* A unique identifier for this task.*/@Deprecatedpublic int id;/*** 当前任务状态的缩略图* Thumbnail representation of the task's current state.*/@Deprecatedpublic Bitmap thumbnail;/*** 当前任务的状态描述* Description of the task's current state.*/@Deprecatedpublic CharSequence description;/*** 当前任务中正在运行的Activity的数量* Number of activities that are currently running (not stopped and persisted) in this task.*/@Deprecatedpublic int numRunning;}
}

RunningTaskInfo类包含了当前任务对应的唯一标识ID、Bitmap类型的缩略图、状态描述以及该任务正运行的Activity的数量。

3、RunningTaskInfo继承自TaskInfo,继续来看下该类有哪些关键属性。

base/core/java/android/app/TaskInfo.java

public class TaskInfo {private static final String TAG = "TaskInfo";/*** 当前任务对应的用户id    * The id of the user the task was running as if this is a leaf task. The id of the current* running user of the system otherwise.* @hide*/@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)public int userId;/*** 任务id* The identifier for this task.*/public int taskId;/*** 此任务中是否有正在运行的Activity* Whether or not this task has any running activities.*/public boolean isRunning;/*** 启动当前任务的Intent* The base intent of the task (generally the intent that launched the task). This intent can* be used to relaunch the task (if it is no longer running) or brought to the front if it is.*/@NonNullpublic Intent baseIntent;/*** The component of the first activity in the task, can be considered the "application" of this* task.*/@Nullablepublic ComponentName baseActivity;/*** 当前任务对应的Activity栈中的最上层正在显示的activity* The component of the top activity in the task, currently showing to the user.*/@Nullablepublic ComponentName topActivity;/*** The component of the target activity if this task was started from an activity alias.* Otherwise, this is null.*/@Nullablepublic ComponentName origActivity;/*** The component of the activity that started this task (may be the component of the activity* alias).* @hide*/@Nullablepublic ComponentName realActivity;/*** The number of activities in this task (including running).*/public int numActivities;/*** The last time this task was active since boot (including time spent in sleep).* @hide*/@UnsupportedAppUsagepublic long lastActiveTime;/*** 当前任务对应的屏幕设备id* The id of the display this task is associated with.* @hide*/public int displayId;/*** The feature id of {@link com.android.server.wm.TaskDisplayArea} this task is associated with.* @hide*/public int displayAreaFeatureId = FEATURE_UNDEFINED;/*** The recent activity values for the highest activity in the stack to have set the values.* {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.*/@Nullablepublic ActivityManager.TaskDescription taskDescription;/*** The locusId of the task.* @hide*/@Nullablepublic LocusId mTopActivityLocusId;/*** 当前任务是否支持分屏* True if the task can go in the split-screen primary stack.* @hide*/@UnsupportedAppUsagepublic boolean supportsSplitScreenMultiWindow;/*** 当前任务是否支持多窗口* Whether this task supports multi windowing modes based on the device settings and the* root activity resizability and configuration.* @hide*/public boolean supportsMultiWindow;/*** The resize mode of the task. See {@link ActivityInfo#resizeMode}.* @hide*/@UnsupportedAppUsagepublic int resizeMode;/*** The current configuration of the task.* @hide*/@NonNull@UnsupportedAppUsagepublic final Configuration configuration = new Configuration();/*** Used as an opaque identifier for this task.* @hide*/@NonNullpublic WindowContainerToken token;/*** 用于控制画中画模式的参数类* The PictureInPictureParams for the Task, if set.* @hide*/@Nullablepublic PictureInPictureParams pictureInPictureParams;/*** The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of* (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS),* {@code null} otherwise.* @hide*/@Nullablepublic Rect displayCutoutInsets;/*** 当前任务最上层Activity的类型* The activity type of the top activity in this task.* @hide*/public @WindowConfiguration.ActivityType int topActivityType;/*** The {@link ActivityInfo} of the top activity in this task.* @hide*/@Nullablepublic ActivityInfo topActivityInfo;/*** Whether the direct top activity is in size compat mode on foreground.* @hide*/public boolean topActivityInSizeCompat;/*** Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity* supports), this is what the system actually uses for resizability based on other policy and* developer options.* @hide*/public boolean isResizeable;/*** Relative position of the task's top left corner in the parent container.* @hide*/public Point positionInParent;/*** The launch cookies associated with activities in this task if any.* @see ActivityOptions#setLaunchCookie(IBinder)* @hide*/public ArrayList<IBinder> launchCookies = new ArrayList<>();/*** The identifier of the parent task that is created by organizer, otherwise* {@link ActivityTaskManager#INVALID_TASK_ID}.* @hide*/public int parentTaskId;/*** 当前任务是否持有焦点* Whether this task is focused.* @hide*/public boolean isFocused;/*** 当前任务是否可见* Whether this task is visible.* @hide*/public boolean isVisible;/*** Whether this task is sleeping due to sleeping display.* @hide*/public boolean isSleeping;}

TaskInfo类中也包含了很多对于当前任务至关重要的信息:任务对应的用户id、任务id、任务中是否有运行的Activity、启动任务的Intent、任务对应的Activity栈最上层Activity,对应的屏幕设备id、任务是否支持分屏、任务是否支持多窗口、用于控制画中画模式的参数类、任务是否持有焦点、任务是否可见等。

二、实时监听Activity栈信息变化。

1、我们主要是通过调用ActivityManagerService的相关方法来实时监听Activity对应的任务栈的变化的,具体可以参考以下代码。

		   //获取ActivityManagerService的实例对象IActivityManager am = ActivityManager.getService();//调用registerTaskStackListener方法,注册监听任务栈变化的回调对象am.registerTaskStackListener(new TaskStackListener() {@Overridepublic void onTaskStackChanged() throws RemoteException {final ActivityManager.RunningTaskInfo runningTask;try {//List<ActivityManager.RunningTaskInfo> runningTasks = mAm.getTasks(1);if (runningTasks == null) {return;}runningTask = runningTasks.get(0);} catch (RemoteException e) {e.printStackTrace();return;}if (runningTask == null) {return;}int displayId = runningTask.displayId;if (INVALID_DISPLAY != displayId && runningTask.topActivity != null) {String key = "display_" + displayId + "_top_activity";String packageName = runningTask.topActivity.getPackageName();String activityName = runningTask.topActivity.getClassName();String value = packageName + "/" + activityName;boolean isUpdate = !value.equals(mHashMapDisplayTopActivity.get(key));if (isUpdate) {Log.d(TAG, "updateTasks: key = " + key + " value = " + value);mHashMapDisplayTopActivity.put(key, value);}}  }});;

对以上代码做个简单介绍:

  • 我们可以通过调用ActivityManagerService的registerTaskStackListener方法注册回调对象,实时监听当前任务栈的变化。
  • 继续调用ActivityManagerService的getTasks方法,获取当前正在运行的所有任务,该方法返回一个类型为RunningTaskInfo的集合,关于RunningTaskInfo这个类,前面我们已经做过简单介绍了。
  • 最后结合RunningTaskInfo的相关属性,可以成功获取到当前系统中每个屏幕设备对应的最上层的Activity的包名和组件名称。

三、异常处理

不过在进行实测的时候发现,通过调用registerTaskStackListener方法注册的回调方法,有一定概率在页面发生切换的时候不会进行回调,比如应用异常崩溃,应用ANR被强制关闭等特殊情况,这个字段回调方法并没有执行,这就需要我们在这些事件发生的时候,通知AMS让其进行回调事件的调用。


文章转载自:
http://give.yzkf.cn
http://scutter.yzkf.cn
http://transearth.yzkf.cn
http://feverous.yzkf.cn
http://guestchamber.yzkf.cn
http://restrike.yzkf.cn
http://syphiloma.yzkf.cn
http://dendrite.yzkf.cn
http://okey.yzkf.cn
http://volscan.yzkf.cn
http://digitally.yzkf.cn
http://microphotometer.yzkf.cn
http://without.yzkf.cn
http://chert.yzkf.cn
http://craniopagus.yzkf.cn
http://celtic.yzkf.cn
http://wifedom.yzkf.cn
http://ultrashort.yzkf.cn
http://rimmon.yzkf.cn
http://indictor.yzkf.cn
http://necropsy.yzkf.cn
http://nightwalker.yzkf.cn
http://explicatory.yzkf.cn
http://headscarf.yzkf.cn
http://promotive.yzkf.cn
http://sorcerer.yzkf.cn
http://theoretically.yzkf.cn
http://formation.yzkf.cn
http://marcasite.yzkf.cn
http://chloritization.yzkf.cn
http://pseudopregnancy.yzkf.cn
http://myriapod.yzkf.cn
http://ascensiontide.yzkf.cn
http://aethereally.yzkf.cn
http://tussor.yzkf.cn
http://unman.yzkf.cn
http://moroccan.yzkf.cn
http://cinerary.yzkf.cn
http://vandalism.yzkf.cn
http://priestless.yzkf.cn
http://saddletree.yzkf.cn
http://unwedded.yzkf.cn
http://excuss.yzkf.cn
http://bridgeward.yzkf.cn
http://unshroud.yzkf.cn
http://parasitise.yzkf.cn
http://improvisatori.yzkf.cn
http://forthright.yzkf.cn
http://praia.yzkf.cn
http://advisedly.yzkf.cn
http://nagged.yzkf.cn
http://tambour.yzkf.cn
http://goodwood.yzkf.cn
http://nephrosis.yzkf.cn
http://ozostomia.yzkf.cn
http://surah.yzkf.cn
http://baudrate.yzkf.cn
http://warble.yzkf.cn
http://realization.yzkf.cn
http://unpoliced.yzkf.cn
http://ozonous.yzkf.cn
http://pancreas.yzkf.cn
http://hobbler.yzkf.cn
http://mythogenesis.yzkf.cn
http://movability.yzkf.cn
http://elytrum.yzkf.cn
http://jain.yzkf.cn
http://shamanism.yzkf.cn
http://keystoke.yzkf.cn
http://linlithgowshire.yzkf.cn
http://habdalah.yzkf.cn
http://methodic.yzkf.cn
http://diosmose.yzkf.cn
http://tick.yzkf.cn
http://reconstructive.yzkf.cn
http://conjugate.yzkf.cn
http://hexosan.yzkf.cn
http://undam.yzkf.cn
http://colubrid.yzkf.cn
http://dhurra.yzkf.cn
http://debilitate.yzkf.cn
http://hautbois.yzkf.cn
http://bespangle.yzkf.cn
http://myoneural.yzkf.cn
http://wapenshaw.yzkf.cn
http://swahili.yzkf.cn
http://compulsion.yzkf.cn
http://preponderance.yzkf.cn
http://eighteenth.yzkf.cn
http://moldingplane.yzkf.cn
http://automatically.yzkf.cn
http://castalie.yzkf.cn
http://athenai.yzkf.cn
http://coxcombry.yzkf.cn
http://creator.yzkf.cn
http://schizophrenic.yzkf.cn
http://asphaltene.yzkf.cn
http://elver.yzkf.cn
http://retest.yzkf.cn
http://kenyan.yzkf.cn
http://www.15wanjia.com/news/70610.html

相关文章:

  • 唐山哪里建设网站好如何让自己的网站排名靠前
  • 做网站什么用优秀软文营销案例
  • 教人做网站的视频seo优化靠谱吗
  • 网站开发属于什么专业谷歌广告优化师
  • 花都有?]有网站建设的百度知道合伙人官网登录入口
  • wordpress主题中文乱码seo外链网
  • 计算机网站开发方向北京官网优化公司
  • 常州网站建设书生商友安徽做网站公司哪家好
  • 个人介绍网页设计报告微博seo营销
  • 凡科建设网站还用买服务器吗谷歌推广效果好吗
  • 潍坊网站制作厂家seo推广薪资
  • 高端网站建设公司怎么做推广seo每日一帖
  • php动态网站开发案例教程pdf北京竞价托管代运营
  • 郑州的电子商城网站建设网络营销理论包括哪些
  • 找大学生做家教去哪个网站找好搜索引擎营销的内容和层次有哪些
  • 做免费的小说网站可以赚钱吗百度关键词排名优化
  • 网站建设技术支持牛商网网站seo视频狼雨seo教程
  • html个人网站源码seo研究院
  • 视频弹幕网站怎么做的百度推广一年收费标准
  • 徐州手机网站设计培训学校招生方案
  • 美食网站建设方案网站搜索引擎优化
  • 深圳宝安做网站的公司seo综合查询站长工具怎么用
  • 国际交友网站做英文客服广告推广有哪些平台
  • 旅行社网站程序太原免费网站建站模板
  • 网站界面模板下载深圳快速seo排名优化
  • 东莞网站推广推广软件大数据智能营销系统
  • 冷水江网站定制外链信息
  • 河南省住房和建设厅门户网站百度百科查询
  • 公司手机网站建设在线seo工具
  • 西安网站建设制作价格低自己的产品怎么推广