「Android11系统开发」上层app通过AIDL监听framework数据

一、适用场景:


在Android系统开发中,需要监听按键、触摸、或者可见窗口大小变化等需求时,你会考虑什么方法来实现呢?通过广播的方式可以实现,但是效果可能并不好。AIDL可以实现跨进程通讯,可以解决以上需求。下面重点分析下如何具体实现,以实现按键监听功能为例,代码按实现后的调用先后来说明。


二、代码说明以及分析实现:


大致的流程图如下


「Android11系统开发」上层app通过AIDL监听framework数据

「Android11系统开发」上层app通过AIDL监听framework数据

​编辑


1、在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java文件中添加监听接口。在interceptKeyBeforeDispatching()方法中获取event传递给自定义监听类SxListenerManager中。


@Override
public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
int policyFlags) {
    *****
    *****
    if (mSystemBooted) {
        //SxListenerManager使用单例,使用前判断是否为null
        if(SxListenerManager.getInstance() != null) {
            //通过系统原生接口截取event事件,传递给自定义SxListenerManager
            boolean status = SxListenerManager.getInstance().postKeyEventToUser(event);
            if(status){
                return -1;
            }
        }
    }
    *****
    *****
}


「Android11系统开发」上层app通过AIDL监听framework数据


2、SxListenerManager.java类主要用于绑定service和定义接口。IBinder.DeathRecipient用于检测远程对象是否存活,由于服务端经常意外停止,我们需要重启service,可以使用linkToDeath 机制。


public class SxListenerManager {
    private final static String TAG = "SxListenerManager";

    private static SxListenerManager mInstance = null;
	private static ISxInputListener mSxListenerService;
	
    private SxListenerManager() {
		bindSxListenerService();
    }
	
	public static SxListenerManager getInstance() {
		if (mInstance == null) {
            synchronized (SxListenerManager.class) {
                if (mInstance == null) {
                    mInstance = new SxListenerManager();
                }
            }
        }
        return mInstance;
    }
	
	private static void bindSxListenerService() {
		
        IBinder service = ServiceManager.getService("Sx_service");
        try {
            mSxListenerService = ISxService.Stub.asInterface(service).getListener();
            service.linkToDeath(deathRecipient, 0);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
	
    private static IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            Log.e("SxListenerManager", "===deathRecipient binderDied===");
            if (mSxListenerService != null) {
                //注销监听和回收资源
                mSxListenerService.asBinder().unlinkToDeath(this, 0);
                mSxListenerService = null;
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
				//service死掉后重启service
                bindSxListenerService();
            }
        }
    };
	public boolean postKeyEventToUser(KeyEvent event){
		boolean ret = false;
		try {
			ret = mSxListenerService.postKeyEventToUser(event);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		return ret;
	}
	
}


「Android11系统开发」上层app通过AIDL监听framework数据


3、ISxInputListener.aidl为AIDL接口类,只定义一个postKeyEventToUser接口,用于传递event事件。


interface ISxInputListener { 
    boolean postKeyEventToUser(in KeyEvent event);
}


「Android11系统开发」上层app通过AIDL监听framework数据


4、SxListenerService.java类继承ISxInputListener,实现postKeyEventToUser方法。该方法调用KeyEventListener类中的sendKeyEventToListener方法。


public class SxListenerService extends ISxInputListener.Stub {
	private static final String TAG = "SxListenerService";

	public SxListenerService(Context context) {
		Log.d(TAG, "====SxListenerService==="); 
	}
	
	@Override
	public boolean postKeyEventToUser(KeyEvent event){
		boolean ret = false;
		Log.d(TAG, "post Key EventToUser = "+event);
		if(KeyEventListener.getInstance() != null){
			ret = KeyEventListener.getInstance().sendKeyEventToListener(event);
		}else{
			Log.d(TAG, "KeyEventListener = null ");
		}
		return ret;
	}
}


「Android11系统开发」上层app通过AIDL监听framework数据


5、KeyEventListener类



public class KeyEventListener {
	private static final String TAG = "KeyEventListener";
	private static KeyEventListener mListener = null;
	private Context mContext = null;
	private RemoteCallbackList mCallbackList = null;
	private HashMap mMap = null;
	
	private KeyEventListener() {
		mCallbackList = new RemoteCallbackList() {
			@Override
			public void onCallbackDied(ISxKeyEventClient client) {
				mMap.remove(client.asBinder());
			}
		};
		mMap = new HashMap();
	}
	
	public static KeyEventListener getInstance() {
		if (mListener == null) {
			synchronized (KeyEventListener.class) {
				if (mListener == null) {
					try {
						mListener = new KeyEventListener();
					} catch (Exception e) {
						e.printStackTrace();
						return null;
					}
				}
			}
		}
		return mListener;
	}

	public void setClient(IBinder client) {
		if (client != null) {
			ISxKeyEventClient keyEventClient = ISxKeyEventClient.Stub.asInterface(client);
			mCallbackList.register(keyEventClient);
			mMap.put(client, keyEventClient);
		}
	}

	public void releaseClient(IBinder client) {
		if (client != null && mMap.size() > 0) {
			ISxKeyEventClient keyEventClient = mMap.get(client);
			mCallbackList.unregister(keyEventClient);
			mMap.remove(client);
		}
	}

	public void setContext(Context context) {
		this.mContext = context;
	}

	public boolean sendKeyEventToListener(KeyEvent arg0) {
		boolean ret = false;
		int count = mCallbackList.beginBroadcast();
		while (count > 0) {
			count--;
			try {
				ret = mCallbackList.getBroadcastItem(count).onKeyEvent(arg0);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		mCallbackList.finishBroadcast();
		return ret;
	}

}


「Android11系统开发」上层app通过AIDL监听framework数据


6、ISxKeyEventClient.aidl为AIDL接口类


interface ISxKeyEventClient {
    boolean onKeyEvent(in KeyEvent key);
}


「Android11系统开发」上层app通过AIDL监听framework数据


7、KeyEventManager.java类,实现最终event事件监听。


public class KeyEventManager{
	private static final String TAG = "KeyEventManager";

	public OnKeyEventListener mSxKeyEventListener = null;

	
	public KeyEventManager(Context context) {
		mSxKeyEventListener = new SxKeyEventListener();
		SxKeyListenerManager.getInstance().registerOnKeyEventListener(mSxKeyEventListener);
	}

	private class SxKeyEventListener implements OnKeyEventListener {
		@Override
		public boolean onKeyEvent(KeyEvent event) {
            //按键监听,所有的event监听均在此处处理
			final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
			final boolean canceled = event.isCanceled();
			int KeyCode = event.getKeyCode();
		
			switch(KeyCode){
				case KeyEvent.KEYCODE_HOME: 
					break;
				case KeyEvent.KEYCODE_BACK:
					if(!down ){
					}
					break;
			}
			return true;
		}
	}
}


「Android11系统开发」上层app通过AIDL监听framework数据


8、SxKeyListenerManager.java类绑定service,注册listener。



public class SxKeyListenerManager {
	private final static String TAG = "SxKeyListenerManager";

	static volatile SxKeyListenerManager mInstance = null;
	private static ISxKeyListener mKeyListenerService = null;

	private SxKeyListenerManager() {
		bindSxSourceService();
	}

	public static SxKeyListenerManager getInstance() {

		if (mInstance == null) {
			synchronized (SxKeyListenerManager.class) {
				if (mInstance == null) {
					mInstance = new SxKeyListenerManager();
				}
			}
		}
		return mInstance;
	}
	private static void bindSxSourceService() {
		IBinder service = ServiceManager.getService("Sx_service");
		try {
			mKeyListenerService = ISxService.Stub.asInterface(service).getKeyListener();
			service.linkToDeath(deathRecipient, 0);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	private static IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
		@Override
		public void binderDied() {
			Log.e("SxKeyListenerManager", "------------deathRecipient binderDied------------");
			if (mKeyListenerService != null) {
				//注销监听和回收资源
				mKeyListenerService.asBinder().unlinkToDeath(this, 0);
				mKeyListenerService = null;
				try {
					Thread.sleep(100);
				} catch (Exception e) {
					e.printStackTrace();
				}
				bindSxSourceService();
			}
		}
	};

	private Client mClient;
	private ArrayList mListeners = new ArrayList();

	private class Client extends ISxKeyEventClient.Stub {
		@Override
		public boolean onKeyEvent(KeyEvent arg0) throws RemoteException {
			boolean ret = false;
			for (OnKeyEventListener l : mListeners) {
				ret = l.onKeyEvent(arg0);
			}
			return ret;
		}
	}

	public boolean registerOnKeyEventListener(OnKeyEventListener listener) {
		if (mClient == null) {
			mClient = new Client();
			try {
				if(mKeyListenerService != null) {
					mKeyListenerService.addClient("KeyEventListener", mClient);
				}
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		mListeners.add(listener);
		return true;
	}
	
	private final Object LOCK = new Object();

	public boolean unregisterOnKeyEventListener(OnKeyEventListener listener) {
		synchronized (LOCK)
		{
			mListeners.remove(listener);
			if (mListeners.size() == 0 && mClient != null) {
				try {
					if(mKeyListenerService != null) {
						mKeyListenerService.removeClient("KeyEventListener", mClient);
					}
					mClient = null;
				} catch (RemoteException e) {
					Log.e(TAG, e.getMessage());
				}
			}
			return true;
		}
	}
}


「Android11系统开发」上层app通过AIDL监听framework数据


9、ISxKeyListener.aidl为AIDL接口类,定义相关的接口。


interface ISxKeyListener {
	IBinder getClient(String name);
	void addClient(String name,IBinder client);
	void removeClient(String name,IBinder client);
}


「Android11系统开发」上层app通过AIDL监听framework数据


10、SxKeyListenerService.java类实现相关的接口。


public class SxKeyListenerService extends ISxKeyListener.Stub {
	private static final String TAG = "SxKeyListenerService";

	public SxKeyListenerService(Context context) {
	}

	@Override
	public IBinder getClient(String name) {
		return null;
	}

	@Override
	public void addClient(String name, IBinder client) {
		if (name.equals("KeyEventListener")) {
			KeyEventListener.getInstance().setClient(client);
		}
	}

	@Override
	public void removeClient(String name, IBinder client) {
		if (name.equals("KeyEventListener")) {
			KeyEventListener.getInstance().releaseClient(client);
		}
	}
}


「Android11系统开发」上层app通过AIDL监听framework数据


11、OnKeyEventListener.java为AIDL接口类。


public interface OnKeyEventListener {

    public boolean onKeyEvent(KeyEvent arg0);

}


「Android11系统开发」上层app通过AIDL监听framework数据


12、ISxService.aidl类为aidl接口类。


interface ISxService {
	ISxInputListener getListener(); 
	ISxKeyListener getKeyListener();
}


「Android11系统开发」上层app通过AIDL监听framework数据


13、SxService.java类用于启动所有service。


public class SxService extends Service {
	private SxListenerService mSxListenerService = null;
	private SxKeyListenerService mSxKeyListenerService = null;
	private Context mContext;

	public SxService() {
	}

	@Override
	public void onCreate() {
		mContext = this;
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		android.os.ServiceManager.addService("Sx_service", mBinder);
		return Service.START_STICKY;
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}


	private final ISxService.Stub mBinder = new ISxService.Stub() {
		@Override
		public ISxInputListener getListener() throws RemoteException {
			if (mSxListenerService == null) {
				mSxListenerService = new SxListenerService(getApplicationContext());
			}
			return mSxListenerService;
		}

		@Override
		public ISxKeyListener getKeyListener() throws RemoteException {
			DebugLog.debug("");
			if (mSxKeyListenerService == null) {
				mSxKeyListenerService = new SxKeyListenerService(getApplicationContext());
			}
			return mSxKeyListenerService;
		}
	}
}


「Android11系统开发」上层app通过AIDL监听framework数据


以上内容全部代码基本已实现,除了监听按键,其他需求也是类似的方法。

数据   系统   app
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章