android socket 长连接

来源:互联网 发布:appserv安装端口 编辑:程序博客网 时间:2024/04/30 03:04

tcp长连接+后台service+异步socket实例

总结一下后台服务编程,以及socket实现是一些注意事项。

1,service的生命周期:

//startService() 启动Service其生命周期为context.startService() ->onCreate()- >onStart()->Service running-->context.stopService() | ->onDestroy() ->Service stop 
//对于bindService()启动Service:context.bindService()->onCreate()->onBind()->Service running-->onUnbind() -> onDestroy() ->Service stop

2,怎么拿到service实例

3,startService()及bindService()使用

4,socket的accept,read,write阻塞解决

好吧,直接上代码

GamepadSocketServer.java

package com.example.gamepaddemo.gamepadserver;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.net.URLDecoder;import org.json.JSONException;import org.json.JSONObject;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.Handler;import android.os.IBinder;import android.os.Message;/** * @author zhouxueliang * 1、接收连接请求,控制手柄界面 * 2、发送数据 */public class GamepadSocketServer extends Service {    public static final int GAMEPAD_REQUEST_START_ACTIVITY = 0;    public static final int GAMEPAD_REQUEST_STOP_ACTIVITY  = GAMEPAD_REQUEST_START_ACTIVITY +1;            /**     * 监听端口     */    private static final int PORT = 24000;         /**     * SocketServer开关标志     */    public boolean isSocketServerStarted = false;            /**     * 客户端Socket     */    private Socket clientSocket = null;    private DataInputStream cInputStream = null;    private DataOutputStream cOutputStream = null;        /**     * Server Socket     */    private ServerSocket serverSocket = null;        /**     * 线程切换使用handler     */    private Handler workHandler = new Handler();        /**     * 界面回调handler     */    private Handler helperListener = null;        /**     * 服务启动是启动socket监听     */    @Override    public void onCreate() {            startSocketServer();        super.onCreate();    }         /**     * 服务销毁是是停止socket监听     */    @Override    public void onDestroy() {        stopSocketServer();        helperListener = null;        super.onDestroy();    }        /**     * 启动socket监听     */    public void startSocketServer() {        if (!isSocketServerStarted) {            try {                /**                 * 启动ServerSocket                 */                serverSocket = new ServerSocket(PORT);                isSocketServerStarted = true;                        } catch (IOException e) {                e.printStackTrace();            }                                    /**             * Accept Socket             */            new Thread(new AcceptRunnable()).start();        }    }            /**     * 停止socket监听     */    public void stopSocketServer() {        if (isSocketServerStarted && serverSocket != null) {            try {                isSocketServerStarted = false;                    if (clientSocket !=null && !clientSocket.isClosed()) {                    clientSocket.close();                    clientSocket = null;                }                serverSocket.close();                serverSocket = null;            } catch (IOException e) {                e.printStackTrace();            }                    }    }        /**     * 设置界面回调监听者     */    public void setHelperListener(Handler listener) {        helperListener = listener;    }            /**     * Socket Accept 线程(非阻塞)     */    public class AcceptRunnable implements Runnable {        @Override        public void run() {            while (isSocketServerStarted) {                try {                    /**                     * 监听连接, 阻塞                     */                    final Socket client  = serverSocket.accept();                                        /**                     * 回调主线程                     */                    workHandler.post(new Runnable() {                        @Override                        public void run() {                            onGetClient(client);                        }                    });                } catch (IOException e) {                    e.printStackTrace();                }                }        }    }            /**     * Socket read 线程(非阻塞)     */    public class RecieverRunnable implements Runnable {        private boolean runnable = true;        @Override        public void run() {            while (runnable) {                String inputString = null;                int len = 0;                try {                    /**                     * 等待read数据包大小,阻塞                     */                    len = cInputStream.readInt();                                        /**                     * read到数据包大小,read数据,阻塞                     */                    if (len > 0) {                        byte[] input = new byte[len];                        int l = -1;                        int readlen = 0;                        while(len-readlen > 0 && (l = cInputStream.read(input, readlen , len-readlen)) != -1){                            readlen += l;                        }                        inputString = URLDecoder.decode(new String(input), "UTF-8");                    }                                    } catch (IOException e) {                    runnable = false;                    e.printStackTrace();                }                                /**                 * 解析请求                 */                final RequestInfo requestInfo = parseInputString(inputString);                if (requestInfo != null) {                    /**                     * read请求,回调主线程                     */                    workHandler.post(new Runnable() {                        @Override                        public void run() {                            onGetRequest(requestInfo);                        }                    });                }            }        }    }            /**     * accept请求,回调主线程     */    private void onGetClient(Socket client) {            if(initClientSocket(client)==0) {            ;        }            }            /**     * read(request)请求,回调主线程     */    private void onGetRequest(RequestInfo info) {            if(info != null) {            if (info.target.equals("GamepadRequest")) {                if (info.type == 0) {                    stopGamepadActivity(info);                }                else {                    startGamepadActivity(info);                }            }        }            }            /**     * 请求拉起界面     */    private void startGamepadActivity(RequestInfo info) {        if (helperListener !=null) {            Message message = helperListener.obtainMessage(GAMEPAD_REQUEST_START_ACTIVITY, info);            helperListener.sendMessage(message);        }    }            /**     * 请求关闭界面     */    private void stopGamepadActivity(RequestInfo info) {        if (helperListener !=null) {            Message message = helperListener.obtainMessage(GAMEPAD_REQUEST_STOP_ACTIVITY, info);            helperListener.sendMessage(message);        }    }            /**     * 往客户端发送数据     */    public void respondMessage(JSONObject obj) {        try {            if (cOutputStream != null) {                String utf8String = new String(obj.toString().getBytes(), "UTF-8");                cOutputStream.writeInt(utf8String.getBytes().length);                cOutputStream.write(utf8String.getBytes());                cOutputStream.flush();            }        } catch (IOException e) {            e.printStackTrace();        }    }            /**     * 初始化客户端数据     */    private int initClientSocket(Socket cSocket) {        try {                        /**             * 重置             */            if  (cInputStream != null) {                cInputStream.close();                cInputStream = null;            }                        if  (cOutputStream != null) {                cOutputStream.close();                cOutputStream = null;            }            if  (clientSocket != null) {                clientSocket.close();                clientSocket = null;            }                        /**             * 重设             */            clientSocket = cSocket;            cInputStream = new DataInputStream(clientSocket.getInputStream());            cOutputStream = new DataOutputStream(clientSocket.getOutputStream());            new Thread(new RecieverRunnable()).start();        } catch (IOException e) {            e.printStackTrace();            return -1;        }        return 0;    }        /**     * 服务的Binder     */    public GamepadServerBinder mBinder = new GamepadServerBinder();        public class GamepadServerBinder extends Binder {                public GamepadSocketServer getService() {            /**             * 返回service实例             */            return GamepadSocketServer.this;        }    }        /**     * 绑定服务     */    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }        /**     * 重新绑定服务     */    @Override    public void onRebind(Intent intent) {        super.onRebind(intent);    }            /**     * 解析数据     */    private RequestInfo parseInputString(String inputString) {        if (inputString != null && inputString.length() > 0) {            JSONObject object = null;            RequestInfo request = null;            try {                object = new JSONObject(inputString);                if (object != null) {                    request = new RequestInfo();                    request.target = object.getString("target");                    request.type = object.getInt("type");                    request.peerId = object.getString("peerId");                    request.pcClientVersion = object.getString("pcClientVersion");                }                return request;            } catch (JSONException e) {                e.printStackTrace();            }        }        return null;    }        /**     * 请求数据结构     */    public static class RequestInfo {        String target;        int    type;        String peerId;        String pcClientVersion;    }}

GamepadServerHelper.java

package com.example.gamepaddemo.gamepadserver;import java.lang.ref.WeakReference;import org.json.JSONException;import org.json.JSONObject;import com.example.gamepaddemo.gamepadview.GamepadActivity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Handler;import android.os.IBinder;import android.os.Looper;import android.os.Message;/** * 负责界面与socket服务的交互 * @author zhouxueliang */public class GamepadServerHelper {    private boolean isServiceStarted = false;        /**     * service     */    private GamepadSocketServer gamepadServer = null;    private Context mContext = null;    /** 单例  **/    private static GamepadServerHelper instance;    public synchronized static GamepadServerHelper getInstance(Context context)    {        if (instance == null) {            instance = new GamepadServerHelper(context);        }        return instance;    }        private GamepadServerHelper(Context context) {        mContext = context;    }            /**      * 监听service回调      */    private MessageListener gamepadServerMessageListener = new MessageListener() {                @Override        public void handleMessage(Message msg) {            switch (msg.what) {            case GamepadSocketServer.GAMEPAD_REQUEST_START_ACTIVITY:            {                RequestInfo  info = (RequestInfo)msg.obj;                Intent intent = new Intent(new Intent(mContext, GamepadActivity.class));                intent.putExtra("type", info.type);                mContext.startActivity(intent);            }                break;            case GamepadSocketServer.GAMEPAD_REQUEST_STOP_ACTIVITY:            {                Intent intent = new Intent(new Intent(mContext, GamepadActivity.class));                intent.putExtra("type", 0);                mContext.startActivity(intent);            }                break;            default:                break;            }        }    };    private Handler helperHander = new StaticHandler(gamepadServerMessageListener);                /**      * ServiceConnection,获取service实例     */    private ServiceConnection mConnection = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {            gamepadServer = null;        }                @Override        public void onServiceConnected(ComponentName name, IBinder service) {            gamepadServer = ((GamepadSocketServer.GamepadServerBinder)service).getService();            gamepadServer.setHelperListener(helperHander);        }    };        /**     *  启动手柄服务     */    public synchronized void startService(){            if(!isServiceStarted) {            isServiceStarted = true;                        Intent intent = new Intent();            intent.setClass(mContext, GamepadSocketServer.class);                        mContext.startService(intent);            mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);        }    }        /**     *  关闭手柄服务     */    public synchronized void stopService(){        if(isServiceStarted) {            isServiceStarted = false;                        Intent intent = new Intent();            intent.setClass(mContext, GamepadSocketServer.class);                        mContext.unbindService(mConnection);            mContext.stopService(intent);            gamepadServer = null;        }    }        /**     *  发送消息     */    public void sendMessage(JSONObject obj) {        gamepadServer.respondMessage(obj);    }        /**     * 用来消除Handle可能导致的泄漏     * 原在Util里,鉴于项目独立性,直接移植     */    public static class StaticHandler extends Handler {        WeakReference<MessageListener> listener;                /**         *          * @param listener         *            必读: 此listener必须由Activity实现该接口(推荐)或者是宿主Activity的类成员 : 这里是弱引用,         *            不会增加变量的引用计数, 使用匿名变量会导致listener过早释放(请参考此类的引用示例)         */        public StaticHandler(MessageListener listener) {            this.listener = new WeakReference<MessageListener>(listener);        }                public StaticHandler(Looper looper, MessageListener listener) {            super(looper);            this.listener = new WeakReference<MessageListener>(listener);        }                @Override        public void handleMessage(Message msg) {            MessageListener listener = this.listener.get();            if (listener != null) {                listener.handleMessage(msg);            }        }    }        /**     * 原在Util里,鉴于项目独立性,直接移植     */    public interface MessageListener {        public void handleMessage(Message msg);    }}

 

原创粉丝点击