看这里:Android必备:Android Socket编程的了解与学习整理

最近学习Android的过程中,由于项目、业务等因素影响,服务端通过Socket进行通信,于是开始学习Socket编程,之前的开发中,很少涉及此 方面的知识学习,本篇就来简单的整理一下,通过Android客户端进行Socket登录的demo,来进行Adnroid Socket编程的学习。

在开始学习之前,先来了解一下Socket,以下内容来自百度百科:

通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

首先,来介绍一下项目的设计,只包含两个UI布局文件:login.xml和main.xml,对应登录页和主页,登录页包含一个用户名的输入框和登录按 钮,点击登录按钮,登录按钮显示文字“正在连接,请稍候...”,通过Socket进行登录,并跳转到主页,如果用户名是admin,则在主页显示“登录 成功!”反之显示“登录失败!”。

下面是demo运行后的具体效果图:

Android必备:Android Socket编程的了解与学习整理Android必备:Android Socket编程的了解与学习整理Android必备:Android Socket编程的了解与学习整理

login.xml:

<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="wrap_content"><EditTextandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:inputType="textPersonName"android:hint="请输入用户名"android:ems="10"android:id="@+id/loginName"/><Buttonandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:text="登录"android:id="@+id/loginBtn"/></LinearLayout>

main.xml:

<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center"android:id="@+id/mainText"/></LinearLayout>

当然通过Socket进行通信的时候,我们需要app拥有网络访问即Internet或Wifi的权限,将下面两行添加到AndroidManifest.xml:

<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/><uses-permissionandroid:name="android.permission.INTERNET"/>

下面开始进行实例的编写,本篇的学习基于TCP/ IP 进行Socket通信,说是Android Socket编程,其实使用的是java.net包下提供的ServerSocket和Socket类,这是一种比较底层的编程方式,Socket类用来建立客户端程序,ServerSocket用来建立服务端程序,首先来看服务端的代码:

packagecom.xx566.socket.server;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintWriter;importjava.net.ServerSocket;importjava.net.Socket;publicclassSocketServer{privatestaticServerSocketserverSocket;publicstaticvoidmain(String[]args)throwsIOException{serverSocket=newServerSocket(8888);while(true){finalSocketsocket=serverSocket.accept();try{//获取输入流BufferedReaderinputStream=newBufferedReader(newInputStreamReader(socket.getInputStream()));//获取输出流PrintWriteroutputStream=newPrintWriter(socket.getOutputStream());//读取输入StringreadString=inputStream.readLine();if("admin".equals(readString)){outputStream.println("登录成功!");}else{outputStream.println("登录失败!");}outputStream.flush();//关闭outputStream.close();inputStream.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}}}

我们在8888端口,实例化了Socket服务端,通过永真循环,来等待客户端Socket的连接。accept()方法返回一个对应客户端的Socket,服务端读取客户端输入,如果输入的是"admin",则输出"登录成功!",反之,输出"登录失败!",接下来,我们主要来看一下客户端LoginActivity的编写,需要注意的是,在Android4.0系统以上的系统中,是不允许在主线程中执行网络相关的请求,否则会抛出NetworkOnMainThreadException异常,所以需要单独的线程向服务端发送Socket,完整代码如下:

packagecom.xx566.socket;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Message;importandroid.view.View;importandroid.widget.Button;importandroid.widget.EditText;importjava.io.*;importjava.net.Socket;publicclassLoginActivityextendsActivity{privateButtonloginBtn;privateEditTextloginName;PrintWriteroutputStream;BufferedReaderinputStream;Socketsocket;privateHandlerhandler=newHandler(){@OverridepublicvoidhandleMessage(Messagemsg){//通过handler处理接收到的消息if(msg.what==1){//跳转到主页面,显示登录结果Intentintent=newIntent(LoginActivity.this,MainActivity.class);intent.putExtra("result",msg.getData());startActivity(intent);}}};/***Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.login);//登录按钮点击事件loginBtn=(Button)findViewById(R.id.loginBtn);loginName=(EditText)findViewById(R.id.loginName);loginBtn.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewview){//点击登录后,显示正在连接服务器loginBtn.setText("正在连接,请稍候...");loginBtn.setClickable(false);finalStringuserName=loginName.getText().toString();//通过Socket登录服务器,简单的传递用户名newThread(){@Overridepublicvoidrun(){//处理接收到的消息Messagemessage=newMessage();message.what=1;Bundlebundle=newBundle();Stringresult="";try{socket=newSocket("192.168.0.32",8888);outputStream=newPrintWriter(socket.getOutputStream());inputStream=newBufferedReader(newInputStreamReader(socket.getInputStream()));outputStream.println(userName);outputStream.flush();//读取结果while(true){result=inputStream.readLine();if(!"".equals(result)){break;}}//关闭inputStream.close();outputStream.close();socket.close();}catch(Exceptione){result="网络异常!";}bundle.putString("result",result);message.setData(bundle);//传递消息handler.sendMessage(message);}}.start();}});}@OverrideprotectedvoidonResume(){super.onResume();loginBtn.setText("登录");loginBtn.setClickable(true);}}

这里使用了Android Handler机制进行了线程间消息的传递,主要是接收服务端响应的结果,启动MainActicity。MainActivity里面显示登录结果,代码如下:

packagecom.xx566.socket;importandroid.app.Activity;importandroid.os.Bundle;importandroid.widget.TextView;publicclassMainActivityextendsActivity{privateTextViewmainText;/***Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);mainText=(TextView)findViewById(R.id.mainText);Bundlebundle=getIntent().getExtras().getBundle("result");mainText.setText(bundle.getString("result"));}}

完整项目地址:http://git.oschina.net/realfighter/SocketDemo

更多相关文章

  1. 【Android增量升级系列_01】 浅谈Android增量更新客户端的实现方
  2. 【Android】socket通信【客户端访问】
  3. 来往 android客户端发布
  4. Android之开源中国客户端源码分析(二)
  5. OSCHINA Android 客户端 - 手机相关软件 - 开源中国
  6. Android腾讯微薄客户端开发教程汇总
  7. struts2服务端与android交互
  8. Android笔记:Socket客户端收发数据
  9. 百度地图android客户端的AndroidMainfest.xml的学习和android版

随机推荐

  1. 一点见解: Android事件分发机制(二)
  2. android的消息处理机制(图+源码分析)——Lo
  3. 初识Android
  4. Invalidate和postInvalidate的区别
  5. android 时间同步
  6. Android(安卓)Layout 介绍
  7. Robotium自动化测试框架使用教程
  8. Google 暑期大学生博客分享大赛 2011 And
  9. Android中的通知—Notification
  10. Android4.0十大特性