Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解

(本文转自: http://blog.csdn.net/yinhaide/article/details/44756989

前言:现在很多APP都需要云的功能,也就是通过网络与服务器交换数据。有的采用tcp/ip协议,但是你必须拥有一个固定ip的服务器,可以购买阿里云服务器之类的,就是贵了点。如果只是个人的小应用的的话可以采用新浪云平台这种免费的服务器,采用的协议是http协议,具体实现方式如下:

方式一、在线登陆

这种方式一般是手机端向服务器提交用户名与密码两个参数,服务器通过数据库中查找匹配,找到与没找到都回复手机一个应答数据即可。

手机端代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
HttpClient httpClient = new DefaultHttpClient();
//这里是你与服务器交互的地址  
String validateUrl = " 
//设置读取超时
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 8000);
//设置读取超时
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 8000);
HttpPost httpRequst = new HttpPost(validateUrl);                 
//准备传输的数据
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
//以post的方式给服务器传一下数据 健-值结构
params.add(new BasicNameValuePair("name""zhangsan"));
params.add(new BasicNameValuePair("password""123"));  
 
try
{
    //发送请求
    httpRequst.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
    //得到响应
    HttpResponse response = httpClient.execute(httpRequst);
    //返回值如果为200的话则证明成功的得到了数据
    if(response.getStatusLine().getStatusCode() == 200){
        StringBuilder builder = new StringBuilder();
        //将得到的数据进行解析
        BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        for(String s =buffer.readLine(); s!= null; s = buffer.readLine()){
            builder.append(s);
        }
        //得到Json对象
        JSONObject jsonObject   = new JSONObject(builder.toString());
        //通过得到键值对的方式得到值,其中success是服务器定义返回的数据
        String result = jsonObject.getString("success");
        Log.e("message", result);
    else{
        Log.e("login","erro");
        result="erro";
    }
catch (Exception e) {
    Log.e("sharehotel","exception");
    result="exception";
}

当然 Menifest必须添加联网权限啦~

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

服务器端代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php  
    require_once("database.php");  
    $db new DB();  
    $name $_POST['name'];  
        $name = iconv("utf-8","gbk",$name);  
    $passwd $_POST['passwd'];  
        $passwd = iconv("utf-8","gbk",$passwd);  
    //查看用户名和密码是否正确  
    $sql "select name from `user_database` where name='%s' and password='%s' limit 1";  
    $sql = sprintf($sql$name$password);  
    $result $db->select($sql);  
    if (!count($result)){  
        $ret['success'] = "false";  
        $ret['msg'] = "fromuser or passwd is invalid";  
        $json = json_encode($ret);  
        echo $json;  
        exit;  
    }     
        //密码或用户名正确  
    $ret['success'] = "true";  
    $ret['msg'] = "success login";  
    $json = json_encode($ret);  
    echo $json;  
    exit;  
?>

前面两行输连接上新浪云平台的数据库,第三行是GBK文字编码转成UTF-8,因为有时候手机端采用的是GBK的编码方式。可以通过eclipse-右键工程-property-Android查看编码方式。再下面就是数据库查询了,如果查询成功即给手机返回json数据(键值格式success-true),如果失败返回false。

附上新浪云数据库函数database.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php  
class DB{  
   
    private $mysql;  
    function __construct($charset="GBK"){  
           
        //使用sae接口连接到数据库  
        $this->mysql = new SaeMysql();  
        $this->mysql->setCharset($charset);       //设置字符集  
    }  
    /** 
     * @return:成功返回数组,失败时返回false 
     */  
    public function select($sql){  
        $result $this->mysql->getData($sql);  
        if ($this->mysql->errno() != 0){  
            die"Error:" $this->mysql->errmsg());  
        }  
        return $result;  
    }  
    /** 
     * @return:运行Sql语句,不返回结果集 
     */  
    public function query($sql){  
        $this->mysql->runSql($sql);  
        if ($this->mysql->errno() != 0){  
            die"Error:".$this->mysql->errmsg());  
        }  
           
    }  
    public function exec($sql){  
        $this->query($sql);  
    }  
    function __destruct(){  
   
        $this->mysql->closeDb();  
   
    }  
    public function get_con(){  
        return $this->mysql;  
    }  
}  
?>

当然,不得不说的是,因为手机端登陆访问服务器是个耗时操作,你不能在主线程中直接调用以上代码,必须要新开辟一个线程处理这些耗时的操作。具体怎么开辟线程处理这里就不多讲了!

方式二:批量的数据获取

相对第一种方式来说,这种方式获得的数据结构更加复杂。比如说,你需要服务器返回给你十条数据,其中每条数据中都包含若干个键值数据,相当于一个二维数组。手机端的请求代码一样,只是在收到数据之后需要解包,因为服务器把数据打包发送来的。

服务器端实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php  
    require_once("database.php");  
    //解码  
    function JSON($array) {  
            arrayRecursive($array'urlencode', true);  
            $json = json_encode($array);  
            return urldecode($json);  
            }  
    function arrayRecursive(&$array$function$apply_to_keys_also = false)  
        {  
            static $recursive_counter = 0;  
            if (++$recursive_counter > 1000) {  
                die('possible deep recursion attack');  
            }  
            foreach ($array as $key => $value) {  
                if (is_array($value)) {  
                    arrayRecursive($array[$key], $function$apply_to_keys_also);  
                else {  
                    $array[$key] = $function($value);  
                }  
            
                if ($apply_to_keys_also && is_string($key)) {  
                    $new_key $function($key);  
                    if ($new_key != $key) {  
                        $array[$new_key] = $array[$key];  
                        unset($array[$key]);  
                    }  
                }  
            }  
            $recursive_counter--;  
        }  
    //解码  
    $db new DB();  
    $content $_POST['content'];  
        $content = iconv("utf-8","gbk",$content);  
    $name $_POST['name'];  
        $name = iconv("utf-8","gbk",$name);  
    $sql "select * from `advice` order by time desc limit 20";  
    $result $db->select($sql);  
    if (!count($result)){  
        $ret['success'] = "false";  
        $ret['msg'] = "no message record";  
        $json = json_encode($ret);  
        echo $json;  
        exit;  
    }  
    $i = 0;  
        foreach ($result as $val){  
            $ret['data'][$i]['remarks'] = iconv("gbk","utf-8",$val['remarks']);  
        $ret['data'][$i]['name'] = iconv("gbk","utf-8",$val['name']);  
            $ret['data'][$i]['time'] = iconv("gbk","utf-8",$val['time']);  
            $ret['data'][$i]['content'] = iconv("gbk","utf-8",$val['content']);  
        $i++;     
    }  
    $ret['success'] = "true";  
    $ret['msg'] = "receiver message success";  
        $json = JSON($ret);  
    echo $json;  
    exit;  
?>

与前面的服务器代码有所不同的是,这段代码在前面多了两个函数,有什么用呢?首先说的是,服务器在获得手机的请求成功之后将一大堆的数据经过json打包发给手机,但是,json是不支持中文的,所以如果需要传输中文的话必须经过前面两个函数进行编码才能传输。最后传给手机的$json变量其实就是一个二维键值数据,只要手机那边经过合理的解析即可。数据库请求成功之后的返回值result其实就是一个二维数组,通过一个类似for循环的foreach函数将数据获取下来之后经过json打包发给手机端。

手机端实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
List<Map<String,Object>>  listiterms=new ArrayList<Map<String,Object>>();  
HashMap<String, Object>  hashmap=new HashMap<String,Object>();  
String result = null;                             
HttpClient httpClient = new DefaultHttpClient();                
//这里是你与服务器交互的地址  
String validateUrl = "http://";                 
//设置读取超时  
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);                
//设置读取超时  
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);                 
HttpPost httpRequst = new HttpPost(validateUrl);                
//准备传输的数据  
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();     
params.add(new BasicNameValuePair("content""example"));  
params.add(new BasicNameValuePair("name""zhangsan"));                                           
try  
{       
    //发送请求  
    httpRequst.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));  
    //得到响应  
    HttpResponse response = httpClient.execute(httpRequst);                           
    //返回值如果为200的话则证明成功的得到了数据  
    if(response.getStatusLine().getStatusCode() == 200)  
    {  
        StringBuilder builder = new StringBuilder();                                    
        //将得到的数据进行解析  
        BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));                   
        for(String s =buffer.readLine(); s!= null; s = buffer.readLine()){  
            builder.append(s);                                                
        }  
        //得到Json对象  
        JSONObject jsonObject   = new JSONObject(builder.toString());  
        //通过得到键值对的方式得到值  
        result = jsonObject.getString("success");//判断时候获得数据  
        if(result.equals("true")){  
            //得到json数据  
            String data = jsonObject.getString("data");    
            //将json数据进行解析  
            JSONArray arr = new JSONArray(data);  
            int i=0;  
            //循环解析json数组,得到一个需要的键-值变量  
            for ( i = 0; i < arr.length(); i++) {   
                Map<String,Object> map=new HashMap<String,Object>();  
                JSONObject temp = (JSONObject) arr.get(i);     
                map.put("remarks", temp.getString("remarks"));  
                map.put("name", temp.getString("name"));  
                Log.e("innername", temp.getString("name"));  
                map.put("content", temp.getString("content"));  
                map.put("time", temp.getString("time"));                                              
                listiterms.add(map);                
            }                                        
        }else{      
            //没有数据  
            hashmap.put("remarks""no_data");  
            listiterms.add(hashmap);  
        }  
                 
    else{  
        //连接失败  
        hashmap.put("remarks""connect_erro");  
        listiterms.add( hashmap);   
    }  
catch (Exception e) {    
    //连接异常  
    hashmap.put("remarks""exception");  
    listiterms.add(hashmap);   
}

与登陆代码不同的是这里多了json数据解析,将二维键值数组存储到List<Map<String,Object>>中,具体怎么用这个结构这里就不多提了。与前面一样的是必须新开线程处理这些耗时的操作。

Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解的更多相关文章

  1. Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解

    前言:  虽然本文标题的有点标题党的感觉,但无论如何,通过这篇文章的学习以及你自己的实践认知,写个简单的滑屏小 Demo还是just so so的. 友情提示: 在继续往下面读之前,希望您对以下知识点 ...

  2. android中在java代码中设置Button按钮的背景颜色

    android中在java代码中设置Button按钮的背景颜色 1.设置背景图片,图片来源于drawable: flightInfoPanel.setBackgroundDrawable(getRes ...

  3. 基于Java的打包jar、war、ear包的作用与区别详解

      本篇文章,小编为大家介绍,基于Java的打包jar.war.ear包的作用与区别详解.需要的朋友参考下   以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.cla ...

  4. Java中对象、对象引用、堆、栈、值传递以及引用传递的详解

    Java中对象.对象引用.堆.栈.值传递以及引用传递的详解 1.对象和对象引用的差别: (1).对象: 万物皆对象.对象是类的实例. 在Java中new是用来在堆上创建对象用的. 一个对象能够被多个引 ...

  5. [PXE] Linux(centos6)中PXE 服务器搭建,PXE安装、启动及PXE理论详解

    [PXE] Linux(centos6)中PXE 服务器搭建,PXE安装.启动及PXE理论详解 本篇blog主要讲述了[PXE] linux(centos)PXE无盘服务器搭建,安装,启动及pxe协议 ...

  6. Android Socket通信详解

    一.Socket通信简介  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...

  7. [转帖]基于VIM漏洞CVE-2019-12735的VIM宏后门病毒详解

    基于VIM漏洞CVE-2019-12735的VIM宏后门病毒详解 不明觉厉 只要是人做的东西 就会有bug 就会有安全问题 就看发现bug 或者是发现安全问题 有没有收益了 会用linux的都是比较熟 ...

  8. Java生鲜电商平台-优惠券系统设计详解

    Java生鲜电商平台-优惠券系统设计详解 优惠券作为电商最常用的营销手段,对于商家而言可以起到拉新.促活.提高转化的作用,对用户而言也可以获得实惠,今天就来谈谈优惠券系统的设计逻辑. 我对于优惠券系统 ...

  9. 《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)

    1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo,然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何自动化测试,这一篇宏哥在网上找了一个问卷调查,给小伙伴或童鞋们来演示一下.上 ...

随机推荐

  1. 找不到请求的 .Net Framework Data Provider。可能没有安装.

    学习中遇到的问题: 找不到请求的 .Net Framework Data Provider.可能没有安装. 找到的解决方法 解决方法: 安装Microsoft SQL Server Compact 4 ...

  2. 12-1 上午mysql 基本语句

    create table test( code varchar(20) primary key, name varchar(20)); 关键字primary key 主键非空 not nullfore ...

  3. magento性能优化

    magento性能优化 14个快速加载web页面的技巧: 减少HTTP请求数使用CDN增加过期头信息gzip压缩传输内容将css样式表放在页首将js文件放在页尾不使用css表达式尽量少用内联式的css ...

  4. XML HttpRequest

    XMLHttpRequest对象提供了在网页加载后与服务器进行通信的方法. 使用XMLHttpRequest对象,能够: 在不重新加载页面的情况下更新网页 在页面已加载后从服务器请求数据,接受数据 在 ...

  5. Link Aggregation and LACP with Open vSwitch

    In this post, I’m going to show you how to use link aggregation (via the Link Aggregation Control Pr ...

  6. 设置drawable图片

    google官方建议在textView和imageView挨着的时候,建议使用drawable来显示图片 第一个方法:setCompoundDrawablesWithIntrinsicBounds(D ...

  7. Eclipse中Egit冲突解决

    Eclipse中Egit冲突解决 Git 作为进来最流行的分布式版本控制软件来说应用的十分广泛.EGit就是一款Eclipse上的Git插件.在使用Egit提交项目时,有时会产生冲突,需要对代码进行m ...

  8. matlab演奏最炫民族风的代码注释

    用Matlab来放音乐,和用单片机加蜂鸣器放音乐的原理都差不多,就是把连续的声音信号事先转换成用数字信号,然后用扬声器按照一定的节奏放出来.换句话说,演唱者是把声音经过麦克风转换成电信号,录音设备对这 ...

  9. Android滑动选择的日期选择框

    效果图如下. 实现也很简单,使用的是Android的DatePicker控件.AlertDialog实现. 首先是布局文件:date_picker_dialog.xml <?xml versio ...

  10. CSS基础知识点(一)

    CSS(Cascading Style Sheets)全称为:层叠样式表. 1.HTML元素类型 (1) 内联元素(inline):可以理解为“文本模式”,即从左到右顺序显示,不单独换行.常用的内联元 ...