Android三种网络通讯方式及Android的网络通讯机制

Android平台有三种网络接口可以使用,他们分别是:java.net.*(标准Java接口)、Org.apache接口和Android.net.*(Android网络接口)。下面分别介绍这些接口的功能和作用。

1.标准Java接口

java.net.*提供与联网有关的类,包括流、数据包套接字(socket)、Internet协议、常见Http处理等。比如:创建URL,以及URLConnection/HttpURLConnection对象、设置链接参数、链接到服务器、向服务器写数据、从服务器读取数据等通信。这些在Java网络编程中均有涉及,我们看一个简单的socket编程,实现服务器回发客户端信息。

下面用个例子来说明:

A、客户端:

新建Android项目工程:SocketForAndroid(这个随意起名字了吧,我是以这个建立的!)

下面是main_activity.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">
 <TextView
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="@string/hello" />
 <EditText
  android:id="@+id/message"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/hint" />
 <Button
  android:id="@+id/send"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:text="@string/send" />
</LinearLayout>

MainActivity.java的代码入下:

package com.yaowen.socketforandroid;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
 private EditText message;
 private Button send;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //初始化两个UI控件
  message = (EditText) findViewById(R.id.message);
  send = (Button) findViewById(R.id.send);
  //设置发送按钮的点击事件响应
  send.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    Socket socket = null;
    //获取message输入框里的输入的内容
    String msg = message.getText().toString() + "\r\n";
    try {
     //这里必须是192.168.3.200,不可以是localhost或者127.0.0.1
     socket = new Socket("192.168.3.200", 18888);
     PrintWriter out = new PrintWriter(
       new BufferedWriter(
         new OutputStreamWriter(
           socket.getOutputStream()
         )
       ), true);
     //发送消息
     out.println(msg);
     //接收数据
     BufferedReader in = new BufferedReader(
      new InputStreamReader(
       socket.getInputStream()
      )
     );
     //读取接收的数据
     String msg_in = in.readLine();
     if (null != msg_in) {
      message.setText(msg_in);
      System.out.println(msg_in);
     } else {
      message.setText("接收的数据有误!");
     }
     //关闭各种流
     out.close();
     in.close();
    } catch (IOException e) {
     e.printStackTrace();
    } finally {
     try {
      if (null != socket) {
       //socket不为空时,最后记得要把socket关闭
       socket.close();
      }
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
   }
  });
 }
}

最后别忘记添加访问网络权限:

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

B、服务端:

package service;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerAndroid implements Runnable {
 @Override
 public void run() {
 Socket socket = null;
 try {
 ServerSocket server = new ServerSocket(18888);
 // 循环监听客户端链接请求
 while (true) {
 System.out.println("start...");
 // 接收请求
 socket = server.accept();
 System.out.println("accept...");
 // 接收客户端消息
 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 String message = in.readLine();
 System.out.println(message);
 // 发送消息,向客户端
 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),
  true);
 out.println("Server:" + message);
 // 关闭流
 in.close();
 out.close();
 }
 } catch (IOException e) {
 e.printStackTrace();
 } finally {
 if (null != socket) {
 try {
  socket.close();
 } catch (IOException e) {
  e.printStackTrace();
 }
 }
 }
 }
 // 启动服务器
 public static void main(String[] args) {
 Thread server = new Thread(new ServerAndroid());
 server.start();
 }
}

C、启动服务器,控制台会打印出“start...”字符串!

D、运行Android项目文件,如下图:

在输入框里输入如下字符串,点发送按钮:

服务器收到客户端发来的消息并打印到控制台:

2、Apache接口

对于大部分应用程序而言JDK本身提供的网络功能已远远不够,这时就需要Android提供的Apache HttpClient了。它是一个开源项目,功能更加完善,为客户端的Http编程提供高效、最新、功能丰富的工具包支持。
下面我们以一个简单例子来看看如何使用HttpClient在Android客户端访问Web。
首先,要在你的机器上搭建一个web应用test,有两个很简单的PHP文件:hello_get.php和hello_post.php!
内容如下:

hello_get.php的代码如下:

<html>
 <body>
 Welcome <?php echo $_GET["name"]; ?><br>
 You connected this page on : <?php echo $_GET["get"]; ?>
 </body>
</html>

hello_post.php的代码如下:

<html>
<body>
Welcome <?php echo $_POST["name"]; ?><br>
You connected this page on : <?php echo $_POST["post"]; ?>
</body>
</html>

在原来的Android项目里新建一个Apache活动类:Apache.java,代码如下:

package com.yaowen.socketforandroid;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by YAOWEN on 2015/11/10.
 */
public class ApacheActivity extends AppCompatActivity implements View.OnClickListener {
 private TextView textView;
 private Button get1, post1;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.apache);
  textView = (TextView) findViewById(R.id.textView);
  get1 = (Button) findViewById(R.id.get);
  post1 = (Button) findViewById(R.id.post);
  get1.setOnClickListener(this);
  post1.setOnClickListener(this);
 }
 @Override
 public void onClick(View v) {
  if (v.getId() == R.id.get) {
   //注意:此处ip不能用127.0.0.1或localhost,Android模拟器已将它自己作为了localhost
   String url = "http://192.168.3.200/test/hello_get.php?name=yaowen&get=GET";
   textView.setText(get(url));
  }
  if (v.getId() == R.id.post) {
   String url="http://192.168.3.200/test/hello_post.php";
   textView.setText(post(url));
  }
 }
 /**
  * 以post方式发送请求,访问web
  *
  * @param url web地址
  * @return 响应数据
  */
 private String post(String url) {
  BufferedReader reader = null;
  StringBuffer sb = null;
  String result = "";
  HttpClient client = new DefaultHttpClient();
  HttpPost requset = new HttpPost(url);
  //保存要传递的参数
  List<NameValuePair> params = new ArrayList<NameValuePair>();
  //添加参数
  params.add(new BasicNameValuePair("name", "yaowen"));
  params.add(new BasicNameValuePair("post","POST"));
  try {
   HttpEntity entity = new UrlEncodedFormEntity(params, "utf-8");
   requset.setEntity(entity);
   HttpResponse response = client.execute(requset);
   if (response.getStatusLine().getStatusCode() == 200) {
    System.out.println("post success");
    reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    sb = new StringBuffer();
    String line = "";
    String NL = System.getProperty("line.separator");
    while ((line = reader.readLine()) != null) {
     sb.append(line);
    }
   }
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  } catch (ClientProtocolException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   if (null != reader) {
    try {
     reader.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   if (null != sb) {
    result = sb.toString();
   }
  }
  return result;
 }
 /**
  * 以get方式发送请求,访问web
  *
  * @param url web地址
  * @return 响应数据
  */
 private static String get(String url) {
  BufferedReader bufferedReader = null;
  StringBuffer sb = null;
  String result = "";
  HttpClient client = new DefaultHttpClient();
  HttpGet request = new HttpGet(url);
  //发送请求,得到响应
  try {
   HttpResponse response = client.execute(request);
   //请求成功
   if (response.getStatusLine().getStatusCode() == 200) {
    bufferedReader = new BufferedReader(
      new InputStreamReader(
        response.getEntity()
          .getContent()
      )
    );
    sb = new StringBuffer();
    String line = "";
    String NL = System.getProperty("line.separator");
    while ((line = bufferedReader.readLine()) != null) {
     sb.append(line);
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   if (null != bufferedReader) {
    try {
     bufferedReader.close();
     //bufferedReader=null;
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   if (null != sb) {
    result = sb.toString();
   }
  }
  return result;
 }
}

新建一个apache.XML文件,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">
 <TextView
  android:id="@+id/textView"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:gravity="center"
  android:text="通过按钮选择不同方式访问网页" />
 <Button
  android:id="@+id/get"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="get" />
 <Button
  android:id="@+id/post"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="post" />
</LinearLayout>

结果运行如下:

3.android.net编程:

常常使用此包下的类进行Android特有的网络编程,如:访问WiFi,访问Android联网信息,邮件等功能。
这里就不详细做例子了,因为这个接触比较多~~~。

下面给大家介绍Android的网络通讯

我们知道,Java提供的Socket可以完成了两台PC机的通信。TCPServer需要客户端和服务器,服务器用SocketServer和Socket完成,客户端使用Socket完成......这些我们都很熟悉。此章主要是通过TCPServer完成Android 与PC机的通信,

首先来看我们熟悉的服务器程序:

上图用主方法main其他一个Thread,然后在run方法里面无限监听发送过来的内容,如果有内容则输出。利用的是Java的API,很经典。

接下来就是在Android端发送数据给PC端,其代码如下:

这样就完成了Android与PC机间的通信。

(0)

相关推荐

  • 详细介绍Android中回调函数机制

    提示:在阅读本文章之前,请确保您对Touch事件的分发机制有一定的了解 在Android的学习过程中经常会听到或者见到"回调"这个词,那么什么是回调呢?所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为回调. 下面我们拿具体的Button的点击事件进行模拟分析: 首先,在View类中我们能找到setOnClickLis

  • Android多线程处理机制中的Handler使用介绍

    接下来让我介绍Android的Handler的使用方法.Handler可以发送Messsage和Runnable对象到与其相关联的线程的消息队列.每个Handler对象与创建它的线程相关联,并且每个Handler对象只能与一个线程相关联. Handler一般有两种用途:1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器.2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息.当你创建子线程时,你可以再你的子线程中拿到父线程中创建的Ha

  • 理解Android系统Binder机制

    一.Binder机制概述 在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的机制有很多种,比如说socket.pipe等,Android中进程间通信的方式主要有三种: 1.标准Linux Kernel IPC 接口: 2.标准D-BUS接口: 3.Binder接口. 其中,Binder机制是使用最且最被认可的,因为Binder机制有以下优点: 1.相对于其它IPC机制,Binder机制更加简洁和快速: 2.消耗的内存相对更少: 3.传统的IPC机制可能会增加

  • Android中利用App实现消息推送机制的代码

    1.消息推送机制 服务器器端需要变被动为主动,通知客户一些开发商认为重要的信息,无论应用程序是否正在运行或者关闭. 我想到了一句话:don't call me,i will call you! qq今天在右下角弹出了一个对话框:"奥巴马宣布本拉登挂了...",正是如此. 自作聪明,就会带点小聪明,有人喜欢就有人讨厌. 2.独立进程 无论程序是否正在运行,我们都要能通知到客户,我们需要一个独立进程的后台服务. 我们需要一个独立进程的后台服务. 在androidmanifest.xml中注

  • Android的Touch事件处理机制介绍

    Android的Touch事件处理机制比较复杂,特别是在考虑了多点触摸以及事件拦截之后. Android的Touch事件处理分3个层面:Activity层,ViewGroup层,View层. 首先说一下Touch事件处理的几条基本规则. 如果在某个层级没有处理ACTION_DOWN事件,那么该层就再也收不到后续的Touch事件了直到下一次ACTION_DOWN事件. 说明: a.某个层级没有处理某个事件指的是它以及它的子View都没有处理该事件. b.这条规则不适用于Activity层(它是顶层

  • android的消息处理机制(图文+源码分析)—Looper/Handler/Message

    这篇文章写的非常好,深入浅出,关键还是一位大三学生自己剖析的心得.这是我喜欢此文的原因.下面请看正文: 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.android源码中包含了大量的设 计模式,除此以外,android sdk还精心为我们设计了各种helper类,对于和我一样渴望水平得到进阶的人来说,都太值得一读了.这不,前几天为了了解android的消息处理机 制,我看了Looper,Handler,Message这几个类的源码,结果又

  • Android4.1中BinderService用法实例分析

    本文实例讲述了Android4.1中BinderService用法.分享给大家供大家参考,具体如下: Android4.1 中出现了一个新的类,BinderService,所有的Native Service 都会继承这个类. class BinderService { public: static status_t publish(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); ret

  • android IPC之binder通信机制

    Binder通信机制说来简单,但是在使用的过程的遇到了一些问题,最后终于解决了,在这总结一下,一并分享给大家: 1.要使用Binder通信,首先要定义接口,然后实现服务端BnInterface***和客户端BpInterface***,说到底一个是把参数解包,一个是把参数打包. 2.服务端要能够接收Binder调用请求,要具备两个条件:一个是实现Bn接口,另一个是调用IPCProcess()->self->startThreadPool() IPCThread()->Self->j

  • Android签名机制介绍:生成keystore、签名、查看签名信息等方法

    Android独有的安全机制,除了权限机制外,另外一个就是签名机制了.签名机制主要用在以下两个主要场合起到其作用:升级App和权限检查. 升级App 用户在升级一款已经安装过的App时,如果程序的修改来自于同一来源,则允许升级安装,否则会提示签名不一致无法安装的提示. 权限检查 我曾在Android Permission权限机制的具体使用一文中提过,对于申请权限的  protection level 为 signature 或者 signatureOrSystem 的,会检查权限申请者和权限声明

  • Android三种方式实现ProgressBar自定义圆形进度条

    进度条样式在项目中经常可以见到,下面小编给大家分享Android三种方式实现ProgressBar自定义圆形进度条. Android进度条有4种风格可以使用. 默认值是progressBarStyle. 设置成progressBarStyleSmall后,图标变小. 设置成progressBarStyleLarge后,图标变大 设置成progressBarStyleHorizontal后,变成横向长方形. 自定义圆形进度条ProgressBar的一般有三种方式: 一.通过动画实现 定义res/a

  • Android三种方式生成矢量图之VectorDrawable类使用详解

    目录 生成矢量图VectorDrawable的三种方式 静态VectorDrawable的使用 配置引用和参数 在控件中使用 生成矢量图VectorDrawable的三种方式 第一种: 选中drawable文件夹,右键New --> Vector Asset --> 选中Clip Art ,在这里面可以选择一些矢量图 ,点击Next,然后 Finish即可. 第二种:(前提:自己有一张svg或psd的图片) 选中drawable文件夹,右键New --> Vector Asset --&

  • Android 三种延迟操作的实现方法

    Android 三种延迟操作的实现方法 实现方法: 一.线程 new Thread(new Runnable(){ public void run(){ Thread.sleep(XXXX); handler.sendMessage();----告诉主线程执行任务 } }).start 二.延时器 TimerTask task = new TimerTask(){ public void run(){ //execute the task } }; Timer timer = new Timer

  • Android 三种动画详解及简单实例

    Android 三种动画详解 帧动画 一张张图片不断的切换,形成动画效果 在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长 <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="

  • Spark三种属性配置方式详解

    随着Spark项目的逐渐成熟, 越来越多的可配置参数被添加到Spark中来.在Spark中提供了三个地方用于配置: 1.Spark properties:这个可以控制应用程序的绝大部分属性.并且可以通过 SparkConf对象或者Java 系统属性进行设置: 2.环境变量(Environment variables):这个可以分别对每台机器进行相应的设置,比如IP.这个可以在每台机器的$SPARK_HOME/ conf/spark-env.sh脚本中进行设置: 3.日志:所有的日志相关的属性可以

  • 深入浅析JavaScript中对事件的三种监听方式

    事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水,当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了. 第一种监听方式,也是最普遍使用的方式,是直接在代码上加载事件,产生效果: <table> <tr onmouseover='this.style.backgroundColor="red"' onmouseout='this.style.backgroundColor=""'><td>

  • 浅谈JS中的三种字符串连接方式及其性能比较

    工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法 用连接符"+"把要连接的字符串连起来: str="a"; str+="b"; 毫无疑问,这种方法是最便捷快速的,如果只连接100个以下的字符串建议用这种方法最方便. 第二种方法 以数组作为中介用 join 连接字符串: var arr=new Array(); arr.push(a);

  • Spring 3.x中三种Bean配置方式比较详解

    以前Java框架基本都采用了XML作为配置文件,但是现在Java框架又不约而同地支持基于Annotation的"零配置"来代替XML配置文件,Struts2.Hibernate.Spring都开始使用Annotation来代替XML配置文件了:而在Spring3.x提供了三种选择,分别是:基于XML的配置.基于注解的配置和基于Java类的配置. 下面分别介绍下这三种配置方式:首先定义一个用于举例的JavaBean. package com.chinalife.dao public cl

  • Javascript三种字符串连接方式及性能比较

    第一种:用连接符"+"连接字符串 str="a"; str+="b"; 这种方法相对以下两种,最便捷快速.建议100字符以下的连接使用这种连接方式. 第二种:以数组作为中介,使用jion函数进行连接 var arr=new Array(); arr.push(a); arr.push(b); var str=arr.join(""); 第三种:利用对象属性连接字符串 function stringConnect(){ this

  • Java HashMap三种循环遍历方式及其性能对比实例分析

    本文实例讲述了Java HashMap三种循环遍历方式及其性能对比.分享给大家供大家参考,具体如下: HashMap的三种遍历方式 (1)for each map.entrySet() Map<String, String> map = new HashMap<String, String>(); for (Entry<String, String> entry : map.entrySet()) { entry.getKey(); entry.getValue();

随机推荐