1. Define the behavior of Socket, SocketAction.java
/** * @Description: Socket behavior */ public interface SocketAction { /** * connection succeeded */ String ACTION_CONNECT_SUCCESS = "action_connect_success"; /** * Connection failed */ String ACTION_CONNECT_FAIL = "action_connect_fail"; /** * Disconnect */ String ACTION_DISCONNECTION = "action_disconnection"; }
2. Create Socket action distribution interface, ISocketActionDispatch.java
/** * @Description: Socket behavior distribution interface */ public interface ISocketActionDispatch { /** * Distribution of Socket behavior * * @param action */ void dispatchAction(String action); /** * Distribution of Socket behavior * * @param action * @param serializable */ void dispatchAction(String action, Serializable serializable); /** * Subscribe to Socket behavior monitoring * * @param iSocketActionListener */ void subscribe(ISocketActionListener iSocketActionListener); /** * Unsubscribe from Socket behavior monitoring * * @param iSocketActionListener */ void unSubscribe(ISocketActionListener iSocketActionListener); /** * Stop dispatch thread * * @throws InterruptedException interrupt exception */ void stopDispatchThread() throws InterruptedException; }
3. Implement behavior distribution interface, create Socket behavior distributor, SocketActionDispatcher.java
/** * @Description: Socket behavior dispatcher */ public class SocketActionDispatcher implements ISocketActionDispatch { /** * The host address to connect to */ private SocketAddress socketAddress; /** * Socket behavior monitoring collection / callback monitoring collection */ private List<ISocketActionListener> actionListeners = new ArrayList<>(); /** * Threads that handle Socket behavior */ private Thread actionThread; /** * Whether to stop distribution */ private boolean isStop; /** * Event consumption queue */ private static final LinkedBlockingDeque<ActionBean> actions = new LinkedBlockingDeque<>(); /** * Operate in the UI main thread */ private MainThreadExecutor mainThreadExecutor = new MainThreadExecutor(); public SocketActionDispatcher(SocketAddress socketAddress) { this.socketAddress = socketAddress; startDispatchThread(); } //Change the host address public void setSocketAddress(SocketAddress socketAddress) { this.socketAddress = socketAddress; } @Override public void dispatchAction(String action) { dispatchAction(action, null); } @Override public void dispatchAction(String action, Serializable serializable) { // Encapsulate the received Socket behavior into the queue ActionBean actionBean = new ActionBean(action, serializable, this); actions.offer(actionBean); } @Override public void subscribe(ISocketActionListener iSocketActionListener) { // Socket behavior monitoring is not empty and the collection does not contain if (iSocketActionListener != null & amp; & amp; !actionListeners.contains(iSocketActionListener)) { actionListeners. add(iSocketActionListener); } } @Override public void unSubscribe(ISocketActionListener iSocketActionListener) { actionListeners. remove(iSocketActionListener); } /** * dispatch thread */ private class DispatchThread extends Thread { public DispatchThread(@NonNull String name) { super(name); } @Override public void run() { // Loop processing Socket behavior distribution information while (!isStop) { try { ActionBean actionBean = actions. take(); if (actionBean != null & amp; & amp; actionBean. mDispatcher != null) { //Get the Socket behavior dispatcher SocketActionDispatcher actionDispatcher = actionBean.mDispatcher; List<ISocketActionListener> copyListeners = new ArrayList<>(actionDispatcher. actionListeners); // collection iterator Iterator<ISocketActionListener> listeners = copyListeners. iterator(); // traverse the collection and notify all listeners while (listeners. hasNext()) { ISocketActionListener listener = listeners. next(); // Dispatch actions to listeners //LogUtil.i(actionBean.mAction); actionDispatcher.dispatchActionToListener(actionBean.mAction, actionBean.mArg, listener); } } } catch (InterruptedException e) { e.printStackTrace(); LogUtil.e(e.getMessage()); } } } } /** * dispatch behavior to listeners * * @param action behavior * @param serializable parameter * @param socketActionListener Socket behavior monitoring */ private void dispatchActionToListener(String action, final Serializable serializable, final ISocketActionListener socketActionListener) { switch (action) { // connection succeeded case ACTION_CONNECT_SUCCESS: mainThreadExecutor.execute(() -> socketActionListener.onSocketConnectSuccess(socketAddress)); break; // Connection failed case ACTION_CONNECT_FAIL: mainThreadExecutor.execute(() -> socketActionListener.onSocketConnectFail(socketAddress, (Boolean) serializable)); break; // Disconnect case ACTION_DISCONNECTION: mainThreadExecutor.execute(() -> socketActionListener.onSocketDisconnect(socketAddress, (Boolean) serializable)); break; } } /** * Start dispatching threads */ private void startDispatchThread() { if (!isStop) { isStop = false; actionThread = new DispatchThread("Dispatch thread"); actionThread. start(); } } @Override public void stopDispatchThread() throws InterruptedException { if (actionThread != null & amp; & amp; actionThread.isAlive() & amp; & amp; !actionThread.isInterrupted()) { isStop = true; // interrupt thread actionThread. interrupt(); actionThread. join(); actionThread = null; //LogUtil.i("stopDispatchThread"); } } }
4. Test Behavior Dispatcher
private void initView(View view) { SocketAddress socketAddress = new SocketAddress("192.168.1.52", 8866); SocketActionDispatcher actionDispatcher = new SocketActionDispatcher(socketAddress); view.findViewById(R.id.but_add_dispatch).setOnClickListener(v -> actionDispatcher.dispatchAction(SocketAction.ACTION_CONNECT_SUCCESS)); view.findViewById(R.id.but_add_listener).setOnClickListener(v -> actionDispatcher.subscribe(listener)); view.findViewById(R.id.but_remove_listener).setOnClickListener(v -> actionDispatcher.unSubscribe(listener)); } //Socket behavior monitoring private ISocketActionListener listener = new ISocketActionListener() { @Override public void onSocketConnectSuccess(SocketAddress socketAddress) { LogUtil.i(socketAddress.getIp()); } @Override public void onSocketConnectFail(SocketAddress socketAddress, boolean isNeedReconnect) { } @Override public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) { } };
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge Java skill tree Network programmingTCP communication 108680 people are learning the system