ActivityManagerService新加listener及触发其回调

2023-11-08

前言

Android版本为7.1,之前调查的时候发现没有太多这个功能实现相关的文章,所以自己来写一篇,第一次分享、记录自己代码,有什么写的不对的地方请见谅。

Android.mk

framework/base/Android.mk中新加一行把新加的aidl文件加入编译

core/java/android/app/ITestListener.aidl

ActivityManager.java

framework/base/core/java/android/app/ActivityManager.java
新加注册监听和注销的接口

import android.app.ITestListener.aidl
public boolean registerTestCallback(ITestListener listener) {
	boolean ret = false;
	try {
		ret = ActivityManagerNative.getDefault().registerTestCallback(listener);
	} catch (RemoteException) {
		ret = false;
		throw e.rethrowFromSystemServer();
	}
	return ret;
}
public boolean unRegisterTestCallback(ITestListener listener) {
	boolean ret = false;
	try {
		ret = ActivityManagerNative.getDefault().unRegisterTestCallback(listener);
	} catch (RemoteException) {
		ret = false;
		throw e.rethrowFromSystemServer();
	}
	return ret;
}

ActivityManagerNative.java

framework/base/core/java/android/app/ActivityManagerNative.java

import android.app.ITestListener.aidl
	case REGISTER_ACTIVITY_FINISH_CALLBACK_TRANSACTION: {
		data.enforceInterface(IActivityManager.descriptor);
		ITestListener listener = ITestListener.Stub.asInterface(data.readStrongBinder());
		boolean result = registerTestCallback(listener);
		reply.writeNoException();
		reply.writeInt(result ? 1 : 0);
		return true;
	}
	case UNREGISTER_ACTIVITY_FINISH_CALLBACK_TRANSACTION: {
		data.enforceInterface(IActivityManager.descriptor);
		ITestListener listener = ITestListener.Stub.asInterface(data.readStrongBinder());
		boolean result = unRegisterTestCallback(listener);
		reply.writeNoException();
		reply.writeInt(result ? 1 : 0);
		return true;
	}
public boolean registerTestCallback(ITestListener listener) throws RemoteException {
	Parcel data = Parcel.obtain();
	Parcel replay = Parcel.obtain();
	data.writeInterfaceToken(IActivityManager.descriptor);
	data.writeStrongInterface(listener);
	mRemote.transact(REGISTER_ACTIVITY_FINISH_CALLBACK_TRANSACTION, data, reply, 0);
	reply.readException();
	boolean res - reply.readInt() != 0;
	data.recycle();
	reply.recycle();
	return res;
}
public boolean unRegisterTestCallback(ITestListener listener) throws RemoteException {
	Parcel data = Parcel.obtain();
	Parcel replay = Parcel.obtain();
	data.writeInterfaceToken(IActivityManager.descriptor);
	data.writeStrongInterface(listener);
	mRemote.transact(UNREGISTER_ACTIVITY_FINISH_CALLBACK_TRANSACTION, data, reply, 0);
	reply.readException();
	boolean res - reply.readInt() != 0;
	data.recycle();
	reply.recycle();
	return res;
}

IActivityManager.java

framework/base/core/java/android/app/IActivityManager.java

import android.app.ITestListener.aidl
public boolean registerTestCallback(ITestListener listener) throws RemoteException
public boolean unRegisterTestCallback(ITestListener listener) throws RemoteException
int REGISTER_ACTIVITY_FINISH_CALLBACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+382;
int UNREGISTER_ACTIVITY_FINISH_CALLBACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+383;

ITestListener.aidl

新加listener文件
framework/base/core/java/android/app/ITestListener.aidl

package android.app;

interface ITestListener {
	void OnNotify();
}

ActivityManagerService.java

framework/base/services/core/java/com/android/server/am/ActivityManagerService.java
service里新加接口,在适当时候触发回调

import android.app.ITestListener.aidl
import android.os.HandlerThread;
	private final Arraylist<TestListenerData>mTestListenerDatas = new ArrayList<TestListenerData>();
	private Object mTestObject = new Object();
	private void handleTestListenerDeath(TestListenerDeath death) {
		int index = -1;
		synchronized(mTestObject) {
			if (null != mTestListenerDatas) {
				for (int i = 0; i < mTestListenerDatas.size(); i++) {
					if (mTestListenerDatas.get(i).getTestListenerDeath() == death) {
						index = i;
						break;
					}
				}
			}
			if (index >= 0) {
				mTestListenerDatas.get(index).getTestListener().asBinder()>unlinkToDeath(death,0);
				mTestListenerDatas.remove(index);
			}
		}
	}

    private class TestListenerDeath implements IBinder.DeathRecipient {
        @Override
        public void binderDied() {
            handleTestListenerDeath(TestListenerDeath.this);
        }
    }	

	private final class TestListenerData {
		private TestListenerDeath mDeath;
		private ITestListener mListener;
	
		public TestListenerData(ITestListener listener, TestListenerDeath death) {
			mDeath = death;
			mListener = listener;
		}
		public ITestListener getTestListener() {
			return mListener;
		}
		public TestListenerDeath getTestListenerDeath() {
			return mDeath;
		}
	}
	private int getIndexOfTestListener(ITestListener listener) {
		int index = -1;
		if (null != listener) {
			for (int i = 0; i < mTestListenerDatas.size(); i++) {
				if (mTestListenerDatas.get(i).getActivityFinishListener().asBinder() == listener.asBinder()) {
					index = i;
					break;
				}
			}
		}
		return index;
	}
	private final static int MESSAGE_TEST = 0;
	private final class TestHandler extends Handler {
		public TestHandler(Looper looper){
			super (looper);
		}
	
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
				case MESSAGE_TEST: {
					synchronized(mTestObject) {
						if (null != mTestListenerDatas){
							for (int i = 0; i < mTestListenerDatas.size(); i++) {
								ITestActivity listener = mTestListenerDatas.get(i).getTestListener();
								try {
									if (listener != null) {
										listener.OnNotify();
									}
								} catch (Throwable e) {
									e.printStackTrace();
								}
							}
						}
					}
				}
				break;
			}
		}
	}
	
	private HandlerThread mHandlerThread1;
	private TestHandler mTestHandler;
	
	// Note: This method is invoked on the main thread but may need to attach various
	// handlers to other threads. So take care to be explicit about the looper.
	public ActivityManagerService(Context systemContext) {
	mContext = systemContext;
	
	mHandlerThread1 = new HandlerThread("ACtivityManagerServiceTestThread");
	mHandlerThread1.start();
	mTestHandler = new TestHandler(mHandlerThread1.getLooper());

在想要触发回调的地方加入:

if (mTestListenerDatas != null && !mTestListenerDatas.isEmpty()) {
	Message msgTest = new Message();
	msgTest.what = MESSAGE_TEST;
	mTestHandler.sendMessage(msgTest);
}

新加接口实现:

	@Override
	public boolean registerTestCallback(ITestListener listener) {
		int index;
		synchronized(mTestObject) {
			if (null != listener) {
				index = getIndexOfTestListener(listener);
	
				if (index < 0) {
					TestListenerDeath death = new TestListenerDeath();
					
					try {
						listener.asBinder().linkToDeath(death, 0);
					} catch (RemoteException e) {
						e.printStackTrace();
					}
					TestListenerDate data = new TestListenerDate(listener, death);
		
					if (null != data) {
						mTestListenerDatas.add(data);
						return true;
					}
				}
			}
			return false;
		}
	}
	
	@Override
	public boolean unRegisterTestCallback(ITestListener listener) {
		int index;
		synchronized(mTestObject) {
			if (null != listener) {
				index = getIndexOfTestListener(listener);
	
				if (index >= 0) {
					mTestListenerDatas.remove(index);
					return true;
				}
			}
			return false;
		}
	}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ActivityManagerService新加listener及触发其回调 的相关文章

  • 将位于 jar 中的文件读取为 java.io.File 对象

    与此类似的问题已发布 但似乎没有一个答案对我的情况有帮助 我正在编写一个程序包 它使用 Google 的凭据来获取 Google Apps 用户 为此 我使用服务帐户 因此为了检索凭据 我需要提供 除其他外 一个 p12 签名文件 Cred
  • java“类文件包含错误的类”错误

    我正在尝试制作一个控制台应用程序来测试我的网络服务 我成功部署了一个网络服务http localhost 8080 WS myWS http localhost 8080 WS myWS我用 wsimport 制作了代理类 wsimport
  • Log4j 未使用属性文件找到自定义附加程序

    我正在尝试使用以下 XML 属性文件在 Eclipse 插件项目中配置 log4j 其中包括一个名为 EclipseLoggingAppender 的自定义附加程序
  • EditText 的高度不会扩展到其父级的高度

    我在滚动视图中放置了编辑文本 高度 match parent并期望它的高度等于滚动视图 但事实并非如此 它的高度就像wrap content这意味着如果 EditText 中没有文本 我必须将光标指向要弹出的软键盘的第一 行 我想要的是我可
  • MPAndroidChart:组合图表

    我在用MPAndroidChart 库 https github com PhilJay MPAndroidChart 我想用CombinedChart创建这样的图表 那可能吗 我尝试了一下 但似乎不起作用 因为 这些条目没有按我的预期工作
  • Tomcat JDBC 池中没有足够的空闲连接

    给定以下 Tomcat JDBC 连接设置
  • 如何加快 jar 签名者的速度?

    我使用 ant 来签署我的 jars 以进行网络启动部署 Ant signjar 在 Web 启动签名时非常慢 如何加快签名过程 我找到了一种可能的解决方案 早些时候 在构建脚本 ant signjar 中 按顺序调用所有 jar 我们使用
  • 在 IntelliJ 中创建可执行 JAR(Java 18、JavaFX 18 Maven 项目),“警告:不支持的 JavaFX 配置...”

    我有一个 Java 18 JavaFX 18 Maven 项目 除了 javaFX 库之外 它还有很多库需要包含在工件中 我想创建一个工件 一个 jar 其中包含所有依赖项 我开始按照这个视频来创建 jar https www youtub
  • jsf 中的类型未找到属性

    我正在尝试调用 jsf 中使用 primefaces 的属性 但我有错误 500 在托管bean PersonelBean 类型上找不到 我正在使用 hibernate jsf 和 spring PersonelBean java Mana
  • 这个finally子句包含close()调用的原因是什么

    我正在学习在线java课程 使用 Java 编程简介 http math hws edu javanotes index html 在 I O 章节中 引入了以下代码 顺便说一下 在本程序的末尾 您将发现我们第一个有用的 try 语句中的
  • 在Java程序中计算zip文件的md5哈希值

    我有一个 zip 文件 在我的 Java 代码中我想计算 zip 文件的 md5 哈希值 有没有我可以用于此目的的 java 库 一些例子将非常感激 谢谢 几周前我通过这篇文章做到了这一点 http www javalobby org ja
  • 如何强制初始化 Hibernate JPA 代理以在 JSON 调用中使用它

    我有一个 Spring 3 JPA 2 0 应用程序 在我的 Controller我需要一个初始化的对象 但我有代理 我需要能够以编程方式初始化它 我需要类似的功能org hibernate Hibernate initialize Obj
  • 我们可以用java定制一个垃圾收集器吗?

    我们知道java的垃圾收集器是一个低优先级线程 在java中我们可以创建任何具有高优先级的线程 那么是否有可能拥有我们自己定制的具有可变优先级的垃圾收集器线程 我们可以根据内存管理的级别进行设置 有人尝试过吗 如果是的话 您能分享一些关于如
  • 如何映射 Map

    I tried ManyToMany cascade CascadeType ALL Map
  • Web服务连接超时和请求超时之间的区别

    WebClientTestService service new WebClientTestService int connectionTimeOutInMs 5000 Map
  • JTable中动态加载大量数据

    这是我的问题 我目前有一个 JTable 其中包含 5 000 到超过 200 000 行 你知道我要说什么了 数据已经加载到内存中了 这不是问题 但是如何 我可以创建一个高效的 JTable 以便它只加载以下行 是可见的 并且任何事件仅作
  • 如何在jpa中共享EntityManagerFactory

    我是 jpa 的新手 这是场景 我正在开发一个 Web 应用程序 其中 多个用户可以登录 当 user1 注销时 我正在使用下面的代码 public static void closeEntityManagerFactory if enti
  • Java applet 是否会违反同源策略

    我需要请求一些东西并从其他域获取信息 我知道由于同源政策 javascript 无法做到这一点 我的另一个选择是通过我的服务器发出代理请求 我不希望请求来自我的服务器的 IP 也不想为我的服务器创建额外的负载 并且希望客户端这样做 是否可以
  • android-如何在谷歌地图上将标记的位置显示为地址

    我已经尝试过 commonsware googlemapsv2 教程 特别是在地图上拖动标记 但现在另一个问题困扰着我 问题是如何将标记的当前位置显示为地图下方或上方的地址 字符串 这是我使用的代码 public class MainAct
  • Android 中带有无尽列表视图滚动的 AsyncTask

    我正在创建一个应用程序 其中我需要有无限的滚动列表视图 我不想在我的应用程序中使用任何库 我在网上看到了一些有助于实现此类列表视图的示例 但我的疑问是 当我的数据来自服务器并在异步任务中进行解析时 如何才能拥有无尽的列表视图 如何从滚动异步

随机推荐