android中,联网操作有http连接和socket连接两大类。由于项目需要,我们采取的是Socket连接。鉴于平时连接频繁,因此把Socket连接放到Service里,需要从服务器端获取数据时,只要调用Service中相应方法即可。

Service大致结构是:

public class InternetService extends Service implements Runnable {    private Socket socket;    private BufferedReader reader;//    private PrintWriter writer;//    private Binder binder;    private Thread td;// 线程,获取服务器端发送来的消息    private String workStatus;// 当前工作状况,null表示正在处理,success表示处理成功,failure表示处理失败    private String currAction; //标记当前请求头信息,在获取服务器端反馈的数据后,进行验证,以免出现反馈信息和当前请求不一致问题。比如现在发送第二个请求,但服务器端此时才响应第一个请求      /**     * 向服务器发送请求     *      * @param action     *                 */    public void sendRequest(String action) {        try {            workStatus = null;            JSONObject json = new JSONObject();            json.put("action", action);            currAction=action;            sendMessage(json);        } catch (Exception ex) {            workStatus = Constant.TAG_FAILURE;            ex.printStackTrace();        }    }    /**     *  返回当前workStatus的值     * /public StringgetWorkStatus(){   return workStatus ;}    /**     * 处理服务器端反馈的数据     *      * @param json     *                 */    private void  dealUploadSuperviseTask(JSONObject json)    {        try{            workStatus=json.getString("result");        }catch(Exception ex)        {            ex.printStackTrace();            workStatus=Constant.TAG_FAILURE;        }    }    /**     * 退出程序时,关闭Socket连接     */    public void closeConnection() {        JSONObject json = new JSONObject();// 向服务器端发送断开连接请求        try {            json.put("action", "exit");            sendMessage(json);// 向服务器端发送断开连接请求            Log.v("qlq", "the request is " + json.toString());        } catch (Exception ex) {            ex.printStackTrace();        }    }    /**     * 连接服务器     */    private void connectService() {        try {            socket = new Socket();            SocketAddress socAddress = new InetSocketAddress(127.0.0,                    8000));            socket.connect(socAddress, 3000);            reader = new BufferedReader(new InputStreamReader(                    socket.getInputStream(), "GBK"));            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(                    socket.getOutputStream(), "GBK")), true);        } catch (SocketException ex) {            Log.v("QLQ", "socketException ");            ex.printStackTrace();            workStatus = Constant.TAG_CONNECTFAILURE;// 如果是网络连接出错了,则提示网络连接错误            return;        } catch (SocketTimeoutException ex) {            ex.printStackTrace();            workStatus = Constant.TAG_CONNECTFAILURE;// 如果是网络连接出错了,则提示网络连接错误            return;        } catch (Exception ex) {            ex.printStackTrace();            workStatus = Constant.TAG_CONNECTFAILURE;// 如果是网络连接出错了,则提示网络连接错误            return;        }    }    /**     * 向服务器发送传入的JSON数据信息     *      * @param json     */    private void sendMessage(JSONObject json) {        if (!isNetworkConnected())// 如果当前网络连接不可用,直接提示网络连接不可用,并退出执行。        {            Log.v("QLQ", "workStatus is not connected!111");            workStatus = Constant.TAG_CONNECTFAILURE;            return;        }        if (socket == null)// 如果未连接到服务器,创建连接            connectService();        if (!InternetService.this.td.isAlive())// 如果当前线程没有处于存活状态,重启线程            (td = new Thread(InternetService.this)).start();        if (!socket.isConnected() || (socket.isClosed())) // isConnected()返回的是是否曾经连接过,isClosed()返回是否处于关闭状态,只有当isConnected()返回true,isClosed()返回false的时候,网络处于连接状态        {            Log.v("QLQ", "workStatus is not connected!111222");            for (int i = 0; i < 3 && workStatus == null; i++) {// 如果连接处于关闭状态,重试三次,如果连接正常了,跳出循环                socket = null;                connectService();                if (socket.isConnected() && (!socket.isClosed())) {                    Log.v("QLQ", "workStatus is not connected!11333");                    break;                }            }            if (!socket.isConnected() || (socket.isClosed()))// 如果此时连接还是不正常,提示错误,并跳出循环            {                workStatus = Constant.TAG_CONNECTFAILURE;                Log.v("QLQ", "workStatus is not connected!111444");                return;            }        }        if (!socket.isOutputShutdown()) {// 输入输出流是否关闭            try {                writer.println(json.toString());            } catch (Exception e) {                // TODO Auto-generated catch block                Log.v("QLQ", "workStatus is not connected!55555666666");                e.printStackTrace();                workStatus = Constant.TAG_FAILURE;            }        } else {            workStatus = Constant.TAG_CONNECTFAILURE;        }    }    /**     * 处理服务器端传来的消息,并通过action头信息判断,传递给相应处理方法     *      * @param str     */    private void getMessage(String str) {        try {            JSONObject json = new JSONObject(str);            String action = json.getString("action");// 提取JSON的action信息,获取当前JSON响应的是哪个操作。            if(!currAction.equals(action))                return;            if (action.equals("getCategory")) {                dealUploadSuperviseTask(json);            }         } catch (Exception ex) {            ex.printStackTrace();            workStatus=Constant.TAG_FAILURE;        }    }                public class InterBinder extends Binder {        public InternetService getService() {            return InternetService.this;        }    }    @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        binder = new InterBinder();        td = new Thread(InternetService.this);// 启动线程        td.start();        return binder;    }    @Override    public void onCreate() {        super.onCreate();        // connectService();    }    @Override    public void onStart(Intent intent, int startId) {        super.onStart(intent, startId);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.v("QLQ", "Service is on destroy");    }    @Override    public boolean onUnbind(Intent intent) {        Log.v("QLQ", "service on onUnbind");        return super.onUnbind(intent);    }    /**     * 循环,接收从服务器端传来的数据     */    public void run() {        try {            while (true) {                Thread.sleep(500);// 休眠0.5s                if (socket != null && !socket.isClosed()) {// 如果socket没有被关闭                    if (socket.isConnected()) {// 判断socket是否连接成功                        if (!socket.isInputShutdown()) {                            String content;                            if ((content = reader.readLine()) != null) {                                getMessage(content);                            }                        }                    }                }            }        } catch (Exception ex) {            try {                socket.close();            } catch (Exception e) {                e.printStackTrace();            }            workStatus = Constant.TAG_CONNECTFAILURE;// 如果出现异常,提示网络连接出现问题。            ex.printStackTrace();        }    }}



在前台页面上,由于前台和后台要进行数据交互,因此需要使用bindService方法绑定服务。

InternetService innetService ;public ServiceConnection internetServiceConnection = new ServiceConnection() {        public void onServiceConnected(ComponentName arg0, IBinder service) {            innetService = ((InternetService.InterBinder) service).getService();        }        public void onServiceDisconnected(ComponentName arg0) {            innetService = null;        }    };



然后在onCreate里,执行

bindService(new Intent(BasicActivity.this, InternetService.class),                internetServiceConnection, Context.BIND_AUTO_CREATE);//BasicActivity是我自己为所有Activity定义的基类,这段代码也是写在BasicActivity里。



由于服务绑定后必须要解除,因此在onDestroy中应加上代码

unbindService(internetServiceConnection);



之所以定义workStatus,是为了让前台知道当前联网操作是否成功。
而定义currAction,则是为了标识好当前请求内容,由于服务器端反馈的信息上也有action头信息标识当前返回的数据对应哪种请求,所以,在发送请求时设置currAction,接收到服务器端反馈数据后,验证和currAction是否一致,如果不一致的话,就不作处理,表示“未等到希望的数据”,如果一致,才能执行下一步操作。这样可以防止数据匹配错误。
至于定义BasicActivity,则是因为软件中很多页面除了中间显示的内容外,头部按钮栏等都一致,此外还有很多共用的代码等,因此定义一个BasicActivity,作为他们的父类,减少代码量,这也是java多态的一种体现。

更多相关文章

  1. asmack杂记
  2. Android(安卓)DataBinding+ViewModel+LiveData小Demo
  3. Android的Http网络请求模型初步
  4. android的aidl进程间通讯(二)
  5. Android(安卓)蓝牙开发(三)蓝牙Hid 开发
  6. MQTT在Android中的使用
  7. android usb连接读取卡片(android打卡机)非nfc读取卡片
  8. ril
  9. Android+struts2+JSON方式的手机开发

随机推荐

  1. 你真的了解数据在堆栈中的存储方式吗?
  2. JavaScript中判断对象是否属于Array类型
  3. Foxwell NT530 BMW评论:我要怎么更新它呢?
  4. css盒模型以及如何计算盒子的宽度
  5. Visual Studio 2019 C++使用log4cplus
  6. 深入了解typeof与instanceof的使用场景及
  7. 你真的知道typeof null的结果为什么是‘o
  8. 推荐!5款Linux常用桌面环境
  9. css详解position五种属性用法及其含义
  10. 深入了解JavaScript中基于原型(prototype)