android小项目 连接PHP开发的服务端

来源:互联网 发布:java wait 参数 编辑:程序博客网 时间:2024/05/22 06:37

github 链接:

https://github.com/RenjiaLu9527/AndroidSampledemocnnctMysqlbyPHP



//随手打开一个记事本 记录开发时的疑惑 有点乱 20160701 - 20160705  [简单的吐槽小程序] Android - php - mysql


////////////////////////////////////////////////////////////start

//新建一个txt文档,不输入任何内容。然后“另存为”,将编码由默认的 ANSI 修改为 Unicode 或 UTF-8。可解决php文件默认编码的问题

////////////////////////////////////////////////////////////end

////////////////////////////////////////////////////////////start

//PHP文件 返回 echo '[OK]'
 public class netthread extends Thread {
        @Override
        public void run() {
            Looper.prepare();
            line = "";
            super.run();


            try {


                URL url = new URL("http://192.168.1.109/mytest/index.php?name=" + user + "&psw=" + passwd);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());
                BufferedReader br = new BufferedReader(isr);
                String readbr;
                while ((readbr = br.readLine()) != null)
                    line += readbr + "\n";


                urlConnection.disconnect();//关闭http连接


            } catch (UnknownHostException e) {
                e.printStackTrace();
                line += e.toString();
            } catch (IOException e) {


                e.printStackTrace();
                line += e.toString();
            } finally {
                Log.i("Mactivity_Thread", "line = " + line);
                Message msg = new Message();
                //  msg.set
                msg.obj = new String(line);
                mHandler.sendMessage(msg);
                Looper.loop();


            }
        }

获取的 line编码通过 msg传到handler后
  @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);


                String strmsg =new String("[OK]");
                msg.obj = new String(msg.obj.toString().replaceAll("\r|\n", ""));


                tvlog.setText("等待服务器回应...\n" + "用户名:" + user + "    密码:" + passwd + "\n服务器反馈信息:[" + msg.obj + "]");
                if (strmsg.equals(msg.obj)) {
                    Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();
                    Intent ntnt_feedback = new Intent(MainActivity.this, feedback.class);
                    startActivity(ntnt_feedback);
                } else {
                    tvlog.setText(tvlog.getText() + "else [" + strmsg + "]");
                }

            }


[OK] 与  [OK] 总是不相等
?why
android view显示其值 
[[OK]]else[[OK]]
其中前面的[[OK]]中 [[ ]]贴的不够紧密  
后[[OK]]中 的 [[ 贴的很紧密
贴不紧的 length() = 5


贴紧的 length() = 2


【解答】
调用此函数处理之后即可去掉其中空格, 
    //处理串
    public String trimInnerSpaceStr(String str) {
        str = str.trim();
        while (str.startsWith(" ")||str.startsWith("\n")) {
            str = str.substring(1, str.length()).trim();
        }
        while (str.endsWith(" ")||str.endsWith("\n")) {
            str = str.substring(0, str.length() - 1).trim();
        }
        return str;
    }
//再次遇到
[!]错误:strFlagInfo[0] FLAG判断不等于OK或ERROR  [[?OK]][[OK]]
php返回 
echo 'OK&'."$name";
android先解码 后分组 再比较时:
"OK".equals(strFlagInfo[0]) 一直false
【解答】
利用正则表达式 去掉其中 非字母 非数字的 隐形字符后就可以了;但是不知为何???
strFlagInfo[0] = new String(strFlagInfo[0].toString().replaceAll("[^0-9a-zA-Z]+", ""));
                strFlagInfo[1] = new String(strFlagInfo[1].toString().replaceAll("[^0-9a-zA-Z]+", ""));


//我保存 txt文件时,发现弹窗“该文件含有 Unicode 格式的字符,若保存ANSI文件将丢失 Unicode字符。。。。”
我一直剪切保存测试到底是哪个字符是 Unicode字符,最后发现是【[[?OK]][[OK]]】中左边的ok有问题,
猜测:【待解决】
20160705
////////////////////////////////////////////////////////////end





////////////////////////////////////////////////////////////start
$sqlr = "SELECT * FROM usercomment
WHERE umID>=1 AND umID<=5";【取出umID 1-5 以及umID所属的 单条完整数据】

$sqlr = "SELECT unID FROM usercomment
WHERE umID>=1 AND umID<=5";【只取出 umID 1-5:12345而不取出附带数据】
不一样;
////////////////////////////////////////////////////////////end





////////////////////////////////////////////////////////////start
String testStr = "abc\\123";//形式表示【abc\\123】; 实际表示 【abc\123】
String [] a = testStr.split("\\\\");//形式表示【\\\\】;实际表示【\\】  

即:split()以 实际【\\】 去划分 形式【abc\\123】得数组【abc】和【123】

////////////////////////////////////////////////////////////end




////////////////////////////////////////////////////////////start

//越来越觉得 模块化 低耦合性代码 的重要性 20160704

////////////////////////////////////////////////////////////end


////////////////////////////////////////////////////////////start
//PHP中 【\\】 URLDecode.Decode解码后为【\】容易组合成为转义字符 所以慎重
正斜杠"/"
           "\\"==> 反斜杠
/叫斜杠  \叫反斜杠
* \n : 回车
* \t : 水平制表符
* \r : 换行
* \f : 换页
* \' :单引号
* \'' : 双引号
* \\ : 反斜杠
////////////////////////////////////////////////////////////end


////////////////////////////////////////////////////////////start
//代码布局的如何给其中控件添加 统一的监听器
    private class feedbackViewOnClikListener implements OnClickListener{


        @Override
        public void onClick(View view) {
            if(view.getid ==)
        }
    }
没有 R.id.xx的id匹配
【解答】
http://www.cnblogs.com/codingblock/p/5090441.html
【  ·方案二:在res/values/下添加ids.xml(名字可随意)文件,代码如下:


1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="my_view" type="id" />
</resources>
   然后在代码中做如下设置即可:


1
my_view.setId(R.id.my_view);】


这样: loadingLayout.setId(R.id.LL_listfooterview);//DIY_id.xml 自定义的id

////////////////////////////////////////////////////////////end




////////////////////////////////////////////////////////////start
android 线程handler发送消息activity
其实这些线程间发送消息,没有什么;关键还是在于构造Handler时传入谁的Looper.
为实现子线程给自己本身发送消息,关键还是在于构造Handler时传入的Looper.
 * 在此就传入该子线程自己的Looper即调用Looper.myLooper(),代码如下:
 * Looper.prepare();
 * mHandlerTest1=new HandlerTest1(Looper.myLooper());
 * Looper.loop();
 * 
 * 所以当mHandlerTest1.sendMessage(message);发送消息时
 * 当然是发送到了它自己的消息队列.
 * 
 * 当子线程中收到自己发送的消息后,可继续发送消息到主线程.此时只要注意构造
 * Handler时传入的Handler是主线程的Handler即可,即getMainLooper().
http://www.bkjia.com/Androidjc/893149.html
//  //临时 Message,防止主线程同时访问 msg导致出错
            Message msg_copy =new Message();
            msg_copy.obj = new String(msg.obj.toString());//新的类,不是引用
            msg_copy.what = msg.what;
            feedback.mhandler.sendMessage(msg_copy);//发送消息 msg以引用形式被发送至 主线程
            Looper.loop();

////////////////////////////////////////////////////////////end



////////////////////////////////////////////////////////////start
//问题:ListView每次刷新都会跑到最顶,而不是停留在刷新前的页面
【解答】 【 //ListView lv设置 TranscriptMode取消‘alwaysScroll’->永远停在最顶端
        lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);】
借鉴:
哈哈,其实我找到问题了。原来在我的listview中加了android:transcriptMode="alwaysScroll"这个属性,
导致有变动都会回到底部。在下拉刷新的时候,
设置[mw_shl_code=java,true]listview.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);
[/mw_shl_code]然后计算下原来的位置,数据刷新Adapter.notifyDataSetChanged();接着就是设置listview.setSelection,
这样基本是平滑的,没有跳动。体验不错哦
////////////////////////////////////////////end////////////////////////////////////////////////////////////////////////////////end////////////////////////////////////

////////////////////////////////////////////end////////////////////////////////////////////////////////////////////////////////end////////////////////////////////////

////////////////////////////////////////////end////////////////////////////////////////////////////////////////////////////////end////////////////////////////////////

20160701 - 20160705  [简单的吐槽小程序] 概述:提供注册 登陆功能登陆 吐槽界面,可在吐槽界面发送文字评论,后台连接php文件,php连接MySql数据库,实现 mysql -php-Android的数据传输, 本例使用 GET方法与php交互。
【工程目录】

 
(布局文件中的 listfoot.xml文件无效,不用)

其中 netthread.java 为 网络传输数据的线程,MainActivity.java为主界面 实现用户名密码登陆功能,feedback.java为吐槽界面 主要是一个带footerview刷新的ListView;特别的是res/values/diy_id.xml文件,这是个自定义xml,是为了解决下面的一个无法获取 在代码布局中的以代码定义的控件 的id(R.id.xx)的问题;

【1.问题】
那就说这个问题吧,

-问题来源:

       //下面这段代码 设置ListView的FooterView,代码布局没有调用xml文件,当我想 设置监听器监听这个footerview时,发现在函数里面直接

 

 

//AddFooterViewtoListView函数开始{loadingLayout.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { }});}//AddFooterViewtoListView函数结尾

</pre>
          
这样设置监听器时,没反应,我感觉也是不行的,这只是一个函数而不是一个类,函数运行结束就结束了所以达不到监听的效果;所以我将 loadingLayout定义成一个 全局变量,在函数外面设置其监听器,
 private LinearLayout loadingLayout;//listview的footerview布局
//OnCreate 函数中 添加FooterView 到ListView        AddFooterViewtoListview();        loadingLayout.setId(R.id.LL_listfooterview);//DIY_id.xml 自定义的id        loadingLayout.setOnClickListener(new feedbackViewOnClikListener());
然后在重写的监听器中:
<pre name="code" class="java">private class feedbackViewOnClikListener implements OnClickListener{        @Override        public void onClick(View view) {            switch (view.getId()){                case R.id.LL_listfooterview:                {
}//略
<pre name="code" class="java" style="font-size: 17.6px; font-weight: bold;">

case R.id.xx这里发现 loadingLayout 没有和他匹配的id,因为他是用代码布局的而不是xml;所以得重新通过其他方式指定一个id,
【摘】http://www.cnblogs.com/codingblock/p/5090441.html
 
//在res/values/下添加ids.xml(名字可随意)文件,代码如下:<?xml version="1.0" encoding="utf-8"?><resources>    <item name="my_view" type="id" /></resources>   //然后在代码中做如下设置即可:my_view.setId(R.id.my_view);】
【1.问题】完美解决
其他问题我在 随笔txt中,大概记录了下,有特别的问题特别说明。
//完整源代码
//MainActivity.java
package com.learn4.wheee.androidclient;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.net.URLEncoder;import java.util.Random;public class MainActivity extends Activity {    private EditText et_username;    private EditText et_userpsw;    private TextView tvlog;    private Button bn_login;//登陆    private Button bn_register;//注册    static String URLLOGIN_PHP = "http://192.168.1.109/mytest/login.php?a_lgninout=";    static String URLLOGIN_PHP_IN = "IN";//登陆    static String URLLOGIN_PHP_RGST = "RGST";//注册    static String sttc_name;//正确的 name ;全局变量 整个acitvity共用一个 name 用户名    private String usernm;//临时 name    private String passwd;//临时 psw    public Handler mainHandler;    private String line;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        et_username = (EditText) this.findViewById(R.id.et_name);        et_userpsw = (EditText) this.findViewById(R.id.et_psw);        bn_login = (Button) findViewById(R.id.bn_login);//登陆        bn_register = (Button) findViewById(R.id.bn_register);//注册        tvlog = (TextView) findViewById(R.id.tv_log);//log信息        bn_login.setOnClickListener(new MainOnClickLstnr());        bn_register.setOnClickListener(new MainOnClickLstnr());        mainHandler = new Handler() {            @Override            public void handleMessage(Message msg) {                super.handleMessage(msg);                if(msg.what == 0){                    //与 php 传输数据流时出错                    tvlog.setText("[!]错误:android-php网络出错 请稍后重试\n耗时:"+msg.getWhen());                    Toast.makeText(MainActivity.this,"网络出错 请稍后重试",Toast.LENGTH_LONG).show();                    Log.i("mainHandler","[!]错误 android-php 网络出错 请稍后重试");                }else {                    //String strmsg = new String(msg.obj.toString().replaceAll("[^0-9a-zA-Z]+", ""));                    String strmsg = new String(netthread.trimInnerSpaceStr(msg.obj.toString()));                    Log.i("mainHandler", "去掉首尾空格的strmsg=" + strmsg);                    //先分组 后解码 (login.php文件返回值为【flag&info】)                    //1-2【分组】                    String[] strFlagInfo = strmsg.split("&");                    if (strFlagInfo.length != 2) {                        Log.i("mainHandler", "strFlagInfo.length!=2 [!]错误 strmsg=" + strmsg);                    }                    //理论上只分成 2 组                    //2-2【解码】并去掉解码后的 首尾空格回车                    try {                        strFlagInfo[0] = netthread.trimInnerSpaceStr(URLDecoder.decode(strFlagInfo[0].toString(), "UTF-8"));                        strFlagInfo[1] = netthread.trimInnerSpaceStr(URLDecoder.decode(strFlagInfo[1].toString(), "UTF-8"));                    } catch (UnsupportedEncodingException e) {                        e.printStackTrace();                    }                    Log.i("mainHandler", "分组 解码后[OK_or_ERROR]?:strFlagInfo[0]=[" + strFlagInfo[0] + "] [login_ok_or_MaxId]?:strFlagInfo[1]=[" + strFlagInfo[1]+"]");                    //判断flag是否为 OK                    strFlagInfo[0] = new String(strFlagInfo[0].toString().replaceAll("[^0-9a-zA-Z]+", ""));                    strFlagInfo[1] = new String(strFlagInfo[1].toString().replaceAll("[^0-9a-zA-Z]+", ""));                    if ("OK".equals(strFlagInfo[0])) {                        //操作成功  RGST//返回OK和最大ID,更新用户名控件值 :【'OK&'+$MaxId;】                        //IN //echo 'OK&login_ok';                        Log.i("mainHandler", "【操作成功】等待判断是什么操作strFlagInfo[0]=" + strFlagInfo[0]+"strFlagInfo[1]="+strFlagInfo[1]);                        if ("LOGINOK".equals(strFlagInfo[1])) {                            //【登陆成功】                            sttc_name = et_username.getText().toString();//                            tvlog.setText("登陆成功\n耗时:"+msg.getWhen());                            Log.i("mainHandler", "【登陆成功】 sttc_name=" + sttc_name + "&跳转到feedback.java");                            //跳转到 feedback.java                            Toast.makeText(MainActivity.this, "【登陆成功】", Toast.LENGTH_SHORT).show();                            Intent ntnt_feedback = new Intent(MainActivity.this, feedback.class);                            startActivity(ntnt_feedback);                        } else {                            //【注册成功】                            sttc_name = new String(strFlagInfo[1]);//末尾加上唯一id                            tvlog.setText("注册成功\n耗时:"+msg.getWhen());                            Log.i("mainHandler", "【注册成功】 sttc_name=" + sttc_name + "&设置EditText_name_psw的值,等待用户点击登陆按钮");                            et_username.setText(sttc_name);                            et_userpsw.setText(passwd);                        }                    } else if ("ERROR".equals(strFlagInfo[0].toString())) {                        //操作失败                        tvlog.setText("[!]错误:php-mysql 连接数据库出错\n"+strmsg+"\n耗时:"+msg.getWhen());//输出错误信息                        Log.i("mainHandler","[!]错误:php-mysql 连接数据库出错");                    }else{                        Log.i("mainHandler","[!]错误:strFlagInfo[0] FLAG判断不等于OK或ERROR\n[["+strFlagInfo[0]+"]][["+"OK"+"]]");                    }                }//if-else msg.what == 0?   -end//                tvlog.setText("等待服务器回应:\n" + "用户名:" + sttc_name + "    密码:" + passwd + "\n反馈信息:[" + strmsg + "]" + strmsg.length());//                if ("OK".equals(strmsg)) {//                    Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();//                    Intent ntnt_feedback = new Intent(MainActivity.this, feedback.class);//                    startActivity(ntnt_feedback);//                } else if ("ERROR".equals(strmsg)) {//                    tvlog.setText(tvlog.getText() + "else [" + "OK" + "OK".length() + "]");//                }            }        };//mainHandler -end//        bn_login.setOnClickListener(new View.OnClickListener() {//            @Override//            public void onClick(View view) {//                sttc_name = et_username.getText().toString();//                passwd = et_userpsw.getText().toString();//////                Log.i("MainActivity_bn_OnClick", "开始登陆-启动线程 连接服务器【" + sttc_name + "】【" + passwd + "】");//                //new netthread().start();//                Intent ntnt_feedback = new Intent(MainActivity.this, feedback.class);//                startActivity(ntnt_feedback);////            }//        });    }//onCreate -end    class MainOnClickLstnr implements View.OnClickListener {        @Override        public void onClick(View view) {            switch (view.getId()) {                case R.id.bn_login:                    Log.i("MainActivityOnClick", "你点击了 登陆按钮");                    usernm = et_username.getText().toString();                    passwd = et_userpsw.getText().toString();                    if (usernm == null || passwd == null) {                        //用户名 或 密码 为空                        EditText boo = (usernm == null) ? et_username : et_userpsw;                        boo.setHint("请输入" + ((usernm == null) ? "用户名" : "密码"));                        break;                    }                    Log.i("case R.id.bn_login:", "开始登陆-启动线程 连接服务器【" + usernm + "】【" + passwd + "】");                    String url_login = "";                    try {                        //编码                        url_login = URLLOGIN_PHP + URLLOGIN_PHP_IN + "&a_name=" + URLEncoder.encode(usernm, "UTF-8") + "&a_psw=" + URLEncoder.encode(passwd, "UTF-8");                    } catch (UnsupportedEncodingException e) {                        e.printStackTrace();                    }                    //启动线程 验证登陆信息                    netthread ntthrd_login = new netthread(url_login, mainHandler);                    ntthrd_login.start();                    break;                case R.id.bn_register:                    Log.i("MainActivityOnClick", "你点击了 注册按钮");                    String name_RGST = netthread.trimInnerSpaceStr("" + android.os.Build.MODEL).toString().replace(" ","");//替换空格                    String psw_RGST = "psw" + (new Random().nextInt(8999) + 1000);//产生 1000 - 9999 的随机数                    //赋值给 未检测是否匹配的全局变量                    usernm = name_RGST;                    passwd = psw_RGST;                    //编码                    String url_rgst = "";                    try {                        url_rgst = URLLOGIN_PHP + URLLOGIN_PHP_RGST + "&a_name=" + URLEncoder.encode(name_RGST, "UTF-8") + "&a_psw=" + URLEncoder.encode(psw_RGST, "UTF-8");                    } catch (UnsupportedEncodingException e) {                        e.printStackTrace();                    }                    Log.i("case R.id.bn_register","即将提交的注册信息 url_rgst="+url_rgst+"【name_RGST】="+name_RGST+"【psw_RGST】="+psw_RGST);                    //启动线程 发送注册信息                    netthread ntthrd_rgst = new netthread(url_rgst, mainHandler);                    ntthrd_rgst.start();                    break;                default:                    break;            }        }    }//MainOnClickLstnr -end//    public class netthread extends Thread {//        @Override//        public void run() {//            Looper.prepare();//            line = "";//            super.run();////            try {////                URL url = new URL("http://192.168.1.109/mytest/index.php?name=" + sttc_name + "&psw=" + passwd);//                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();//                InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());//                BufferedReader br = new BufferedReader(isr);//                String readbr;//                while ((readbr = br.readLine()) != null)//                    line += readbr + "\n";////                isr.close();//                urlConnection.disconnect();//关闭http连接////            } catch (UnknownHostException e) {//                e.printStackTrace();//                line += e.toString();//            } catch (IOException e) {////                e.printStackTrace();//                line += e.toString();//            } finally {////                Log.i("Mactivity_Thread", "line = " + line);//                Message msg = new Message();//                //  msg.set//                msg.obj = new String(line);//                mHandler.sendMessage(msg);//                Looper.loop();////            }//        }//    }}//ALL END

//2 feedback.java
package com.learn4.wheee.androidclient;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.view.inputmethod.InputMethodManager;import android.widget.AbsListView;import android.widget.Button;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.SimpleAdapter;import android.widget.TextView;import android.widget.Toast;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.net.URLEncoder;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;/** * Created by Wheee on 2016/7/2. */public class feedback extends Activity {    private String username;    private String usercomment;    //footerview的文字 与 圆形进度框    private ProgressBar progressBar;    private TextView textView;    private EditText et_comment;    private Button bn_send;    static Handler mhandler;    static String URLBASE = "http://192.168.1.109/mytest/write.php?a_wORr=";    static String URLBASE_WRT = "write";    static String URLBASE_RD = "read";    static int LISTITEMNUM = 15;//默认显示 20 条listitem    private int LISTITEMNOW=0;//当前共显示了多少条ListView    private int LISTVISIBCOUNT = 0;//当前页面可以显示多少条数据    List<HashMap<String, String>> mylist;//mylist每次获取 都更新里面所有值    ListView lv;//ListView    private LinearLayout loadingLayout;//listview的footerview布局    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.feedback_layout);        lv = (ListView) findViewById(R.id.lv_a);        et_comment = (EditText) findViewById(R.id.et_comment);        bn_send = (Button) findViewById(R.id.bn_send);        //将MainActivity 的name 赋值 到这里        username = MainActivity.sttc_name;        //ListView lv设置 TranscriptMode取消‘alwaysScroll’->永远停在最顶端        lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED);        //设置监听器        bn_send.setOnClickListener(new feedbackViewOnClikListener());//初始化        //添加FooterView 到ListView        AddFooterViewtoListview();        loadingLayout.setId(R.id.LL_listfooterview);//DIY_id.xml 自定义的id        loadingLayout.setOnClickListener(new feedbackViewOnClikListener());        mylist = new ArrayList<HashMap<String, String>>();//每次全部替换其值        // et_comment.setText("http://192.168.1.109/mytest/write.php?a_user=lurenyi&a_comment=吐槽几句abc123&a_time=2016-07-03-11:00:01");        //接收 netthread 线程反馈消息 msg.what 1:0        mhandler = new Handler() {            @Override            public void handleMessage(Message msg) {                super.handleMessage(msg);                //判断是否 为 write 返回值,不是则为 read                //操作成功 时                Log.i("handleMessage","【读】【写】 操作判断msg.what="+msg.what+"msg.obj="+msg.obj.toString());                if (netthread.SUCCEED_FLAG_WRT.equals(msg.obj.toString())) {                    //【写】操作成功                    Toast.makeText(feedback.this,"【写】 操作成功",Toast.LENGTH_SHORT).show();                    Log.i("handleMessage","【写】 操作成功msg.what="+msg.what);                } else if (msg.what == 1) {                    //【读】操作成功                    //read  则msg.obj储存着read数据,已被处理去掉首位空格换行//                    try {//                        //解码 UTF-8  PHP中 【/】解码后为【/】//                        msg.obj = URLDecoder.decode(msg.obj.toString(), "UTF-8");//                    } catch (UnsupportedEncodingException e) {//                        e.printStackTrace();//                    }                    //先分组 再解码                    //【分组】PHP中 【/】解码后为【/】,待处理串中只剩 【/】                    String[] UserCommTime = msg.obj.toString().split("/");// 形式表示【\\\\】 可以正确划分 形式表示为【\\】的数组                   //【解码】                    String str="";//临时变量                    for(int i=0;i<UserCommTime.length;i++) {                        try {                            str = URLDecoder.decode(UserCommTime[i], "UTF-8");                        } catch (UnsupportedEncodingException e) {                            e.printStackTrace();                        }                        UserCommTime[i]=new String(str.toString());                    }//解码完毕                    //处理末尾的 【读】成功标志位                    UserCommTime[UserCommTime.length - 1] = netthread.trimInnerSpaceStr(UserCommTime[UserCommTime.length - 1]);                    Log.i("handleMessage", "处理末尾的 【读】成功标志位" + UserCommTime[UserCommTime.length - 1]);                    if (netthread.SUCCEED_FLAG_RD.equals(UserCommTime[UserCommTime.length - 1]))//"ROK" == 数组最后的分组,理论上是ROK                    {                        //Toast.makeText(feedback.this, "确定为 【读】 操作" + UserCommTime[UserCommTime.length - 1], Toast.LENGTH_LONG).show();                        Log.i("handlMessage", "" + "确定为 【读】 操作" + UserCommTime[UserCommTime.length - 1]);                        //【读】成功                        //确定不是【写】操作,且获取到【读】操作成功FLAG                        //调用 ListSetAdapter(listview,拆分成数据整条的String数组)                        ListSetAdapter(UserCommTime);//mylist每次全部替换其值                        //【读】完成后 textview改变值, progressBar隐藏                        textView.setText("【加载完成】点击加载更多...");                        progressBar.setVisibility(View.GONE);                        textView.setFocusableInTouchMode(true);                    }                }                //操作 失败和成功都显示                //Toast.makeText(feedback.this, msg.what == 1 ? "Done" : ("Failed" + msg.obj.toString()), Toast.LENGTH_LONG).show();                Log.i("handlMessage", "" + (msg.what == 1 ? "Done" + msg.obj.toString() : ("Failed" + msg.obj.toString())));            }        };        //第一次运行前 获取 listitem 显示        //必须先 创建handler实例 ,第一次只更新 LISTITEMNUM 数量的ListItem        final netthread ntthrd_fstread = new netthread(URLBASE + URLBASE_RD + ("&a_nowid=" + LISTITEMNUM),mhandler);        ntthrd_fstread.start();        //ListView 滑动监听        lv.setOnScrollListener(new AbsListView.OnScrollListener() {            private String url_read = URLBASE + URLBASE_RD;//读取mysql数据            private int lastItemIndex;//是否滑到底了            //private netthread ntForread = new netthread("test");            @Override            public void onScrollStateChanged(AbsListView absListView, int scrollState) {               // Log.i("onScrollStateChanged", "scrollState = " + scrollState);            }            @Override            public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                Log.i("onScroll", "firstVisibleItem = " + firstVisibleItem + "  visibleItemCount=" + visibleItemCount + "  totalItemCount=" + totalItemCount);                lastItemIndex = firstVisibleItem + visibleItemCount - 1;//第一个可见的 加上当前页面可见的listitem数目 = 总共-1                //更新 【当前共显示多少条ListItem】                LISTITEMNOW = totalItemCount-1;                LISTVISIBCOUNT=visibleItemCount;//当前页面显示多少条                Log.i("lastItemIndex", "滑动停止 最新数据条数:lastItemIndex = " + lastItemIndex+"\nLISTITEMNOW="+LISTITEMNOW+" LISTVISIBCOUNT="+LISTVISIBCOUNT);                //lastItemIndex 索引等于 totalItemCount - 1 时,到达最下面的一个,可以加载刷新view了//                if (lastItemIndex >= 0 && lastItemIndex == totalItemCount - 1 && !ntForread.isAlive()) {//                   // Toast.makeText(feedback.this, "刷新中...", Toast.LENGTH_SHORT).show();//                    //ntForread = new netthread(url_read + ("&a_nowid=" + lastItemIndex));//                    // ntForread.start();//                    Log.i("onScroll_ntForread", "ntForread.isAlive()线程不在活动中 启动线程开始读取listitem");//                } else if (ntForread.isAlive()) {//                    Toast.makeText(feedback.this, "正在刷新中 请稍后...", Toast.LENGTH_SHORT).show();////                }            }        });    }//Create 函数end    //更新 ListView 数据 ;类作为函数参数传递时,传递的是引用    public void ListSetAdapter(String[] StrData) {        Log.i("进入ListSetAdapter", "进入ListSetAdapter函数" + StrData.length);        //组织数据源        mylist = new ArrayList<HashMap<String, String>>();//mylist每次全部替换其值        //处理StrData ,urlencode($row["User"]).'+'.urlencode($row["Comment"]).'+'.urlencode($row["Time"]).'\\';        for (int i = StrData.length-2; i>=0; i--) {            HashMap<String, String> map = new HashMap<String, String>();//中间变量 Hashmap初始定义            String[] singleData = StrData[i].split("&");//【&】分割符            Log.i("", "singleData长度" + singleData.length);            singleData[1] = "[" + singleData[2] + "]: " + singleData[1];//singleData[1] = Time + Comment 合并为一条数据            map.put("itemuser", "" + singleData[0]);//USER name            map.put("itemcomment", "" + singleData[1]);//USER comment            mylist.add(map);//添加一条数据        }//        //配置适配器        SimpleAdapter adapter = new SimpleAdapter(                this, mylist, R.layout.listitem, new String[]{"itemuser", "itemcomment"},                new int[]{R.id.tv_user, R.id.tv_comment}        );       // adapter.notifyDataSetChanged();//强制刷新 新的 ListView        //添加进去        lv.setAdapter(adapter);        //判断是否第一次显示 而不是后序的 加载更多        lv.setSelection((!(LISTITEMNOW==-1 &&LISTVISIBCOUNT == 0))?(LISTITEMNOW-LISTVISIBCOUNT+2):0);//总共显示了多少条数据 - 当前页面显示多少条        Log.i("进入ListSetAdapter", "ListView数据添加结束LISTITEMNOW="+LISTITEMNOW+" LISTVISIBCOUNT="+LISTVISIBCOUNT);    }    private void AddFooterViewtoListview() {        /**         * 设置布局显示属性         */        LinearLayout.LayoutParams mLayoutParams = new LinearLayout.LayoutParams(                LinearLayout.LayoutParams.WRAP_CONTENT,                LinearLayout.LayoutParams.WRAP_CONTENT);        /**         * 设置布局显示目标最大化属性         */        LinearLayout.LayoutParams FFlayoutParams = new LinearLayout.LayoutParams(                LinearLayout.LayoutParams.MATCH_PARENT,                LinearLayout.LayoutParams.MATCH_PARENT);        //线性布局        LinearLayout layout = new LinearLayout(this);        //设置布局水平方向        layout.setOrientation(LinearLayout.HORIZONTAL);        //进度条       // final ProgressBar progressBar = new ProgressBar(this);        progressBar = new ProgressBar(this);        progressBar.setVisibility(View.GONE);//不占用空间 不可见        //把进度条加入到layout中        layout.addView(progressBar, mLayoutParams);        //文本内容       // final TextView textView = new TextView(this);        textView = new TextView(this);        textView.setText("【加载完成】点击加载更多...");//        textView.setTextSize(28);//setTextSize()默认的单位是sp        textView.setGravity(Gravity.CENTER_VERTICAL);//        textView.setOnClickListener(new View.OnClickListener() {//            @Override//            public void onClick(View view) {//                textView.setText("加载中...");//                progressBar.setVisibility(View.VISIBLE);//可见//            }//        });        //把文本加入到layout中        layout.addView(textView, FFlayoutParams);        //设置layout的重力方向,即对齐方式是        layout.setGravity(Gravity.CENTER);        //设置ListView的页脚layout        loadingLayout = new LinearLayout(this);        loadingLayout.addView(layout, mLayoutParams);        loadingLayout.setGravity(Gravity.CENTER);        lv.addFooterView(loadingLayout);    }    //feedbackViewOnClikListener feedbackView事件监听器    private class feedbackViewOnClikListener implements OnClickListener{        @Override        public void onClick(View view) {            switch (view.getId()){                case R.id.LL_listfooterview:                {                    Log.i("feedbackView点击监听器","你点击了 ListView的footerview加载更多");                    //显示 圆形进度条                    progressBar.setVisibility(View.VISIBLE);//可见//感觉这是不安全的做法                    textView.setText("加载中...");                    //获取数据库 更新ListView;LISTITEMNUM + LISTITEMNOW条数据                    netthread ntthrd_read = new netthread(URLBASE + URLBASE_RD + ("&a_nowid=" + (LISTITEMNUM+LISTITEMNOW)),mhandler);                    ntthrd_read.start();                    break;                }                case R.id.et_comment:                {                    Log.i("feedbackView点击监听器","你点击了 评论编辑框");                }                case R.id.bn_send:                {                    //判断是否为空                    if(et_comment.getText().toString().equals(""))                    {                        et_comment.setFocusable(true);                        et_comment.setFocusableInTouchMode(true);                        break;}                    Log.i("feedbackView点击监听器","你点击了 发送评论的按钮");                    //发送数据                    String url_write = URLBASE + URLBASE_WRT;                    SimpleDateFormat myfmt = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss ");                    Date dt = new Date();                    //获取 View 数据                 //   username = netthread.trimInnerSpaceStr(""+android.os.Build.MODEL);                    usercomment = et_comment.getText().toString();                    String timestr = new String(myfmt.format(dt));                    try {                        url_write = url_write + "&a_user=" +                                (URLEncoder.encode(username, "utf-8")) + "&a_comment=" +                                URLEncoder.encode(usercomment, "utf-8") + "&a_time=" +                                URLEncoder.encode(timestr, "utf-8");                    } catch (UnsupportedEncodingException e) {                        e.printStackTrace();                    }                    Log.i("setOnClickListener_启动线程", url_write + "");                    //启动线程                    netthread nt_write = new netthread(url_write,mhandler);                    nt_write.start();                    et_comment.setText("");                    //关闭输入法 如果输入法在窗口上已经显示,则隐藏,反之则显示                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);                    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);                    //创建线程更新 ListView                    //获取数据库 更新ListView;LISTITEMNUM + LISTITEMNOW条数据                    netthread ntthrd_read = new netthread(URLBASE + URLBASE_RD + ("&a_nowid=" + (LISTITEMNUM+LISTITEMNOW)),mhandler);                    ntthrd_read.start();                }            }        }    }}//        //点击 提交按钮发送至服务器mysql存储//        bn_send.setOnClickListener(new OnClickListener() {//            @Override//            public void onClick(View view) {////                String url_write = URLBASE + URLBASE_WRT;////                SimpleDateFormat myfmt = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss ");////                Date dt = new Date();////////////                //获取 View 数据////                username = netthread.trimInnerSpaceStr(""+android.os.Build.MODEL);////                usercomment = et_comment.getText().toString();////                String timestr = new String(myfmt.format(dt));////////                try {////                    url_write = url_write + "&a_user=" +////                            (URLEncoder.encode(username, "utf-8")) + "&a_comment=" +////                            URLEncoder.encode(usercomment, "utf-8") + "&a_time=" +////                            URLEncoder.encode(timestr, "utf-8");////                } catch (UnsupportedEncodingException e) {////                    e.printStackTrace();////                }////                Log.i("setOnClickListener_启动线程", url_write + "");////                //启动线程////                netthread nt_write = new netthread(url_write);////                nt_write.start();////                et_comment.setText("");//            }//        });//setOnClickListener函数end

//3 netthread.java 网络线程
package com.learn4.wheee.androidclient;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.net.UnknownHostException;public class netthread extends Thread {    private String threadInfo;    private String urlstring;    static Message msg = new Message();    private Handler ntthrd_handler;//未指定activity的handler    static String SUCCEED_FLAG_WRT = "WOK";//操作成功后服务器的返回值 write    static String SUCCEED_FLAG_RD = "ROK";// read//    static boolean issucceed = false;    netthread(String url,Handler h) {        this.urlstring = url;        this.ntthrd_handler = h;//指定activity    }    @Override    public void run() {        Looper.prepare();        super.run();        threadInfo = "";        msg.obj = null;        msg.what = 0;//初始化 //0-ERROR 表示android端与php传输数据流是出错 而不是mysql与php之间的错误        try {            //GET方式发送数据            URL url = new URL(urlstring);            //接收服务器反馈            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();            InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());            BufferedReader br = new BufferedReader(isr);            String strbr="",Allstrbr="";//中间变量            while ((strbr = br.readLine()) != null)                Allstrbr += strbr + "\n";            threadInfo = Allstrbr;//赋值,去除threadInfo的初始值            isr.close();//流 关闭            urlConnection.disconnect();//关闭http连接            msg.what = 1;//可能出错的语句 全部执行完毕        } catch (UnknownHostException e) {            e.printStackTrace();            threadInfo += e.toString() + "AND";            msg.what = 0;//ERROR        } catch (IOException e) {            e.printStackTrace();            threadInfo += e.toString() + "AND";            msg.what = 0;//ERROR 与php传输数据流是出错 而不是mysql与php之间的错误        } finally {            //简单处理 去掉首位空格换行            threadInfo = trimInnerSpaceStr(threadInfo);            Log.i("我是线程:netthread", "android-php 网络传输过程的信息threadInfo=" + threadInfo);            msg.obj = new String(threadInfo);            //临时 Message,防止主线程同时访问 msg导致出错            Message msg_copy =new Message();            msg_copy.obj = new String(msg.obj.toString());//新的类,不是引用            msg_copy.what = msg.what;            //feedback.mhandler.sendMessage(msg_copy);//发送消息 msg以引用形式被发送至 主线程            this.ntthrd_handler.sendMessage(msg_copy);            Looper.loop();        }    }    //处理串 去掉String 首位所有 换行 空格    static String trimInnerSpaceStr(String str) {        str = str.trim();        while (str.startsWith(" ") || str.startsWith("\n")) {            str = str.substring(1, str.length()).trim();        }        while (str.endsWith(" ") || str.endsWith("\n")) {            str = str.substring(0, str.length() - 1).trim();        }        return str;    }}

//listitem.xml ListView的单条数据布局文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/list_item"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:layout_weight="1"    android:background="#F0FFFF"    android:orientation="horizontal"    android:paddingTop="10dp"    android:paddingBottom="10dp">    <TextView        android:id="@+id/tv_user"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="0.2"        android:text="用户 甲"        android:textColor="#000000"        android:textSize="20sp" />    <ScrollView        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="0.8">        <TextView            android:id="@+id/tv_comment"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:includeFontPadding="true"            android:scrollHorizontally="true"            android:text="我想吐槽的是......" />    </ScrollView></LinearLayout>

//feedback_layout.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <LinearLayout        android:id="@+id/LL_lv"        android:layout_marginTop="130px"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">        <ListView            android:id="@+id/lv_a"            android:layout_width="match_parent"            android:layout_height="wrap_content"             />    </LinearLayout>    <LinearLayout        android:focusable="true"        android:focusableInTouchMode="true"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginBottom="100px"        android:orientation="horizontal"        android:background="#FFFAF0"        android:weightSum="1">        <EditText            android:id="@+id/et_comment"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="0.8"            android:hint="  吐槽点什么吧.." />        <Button            android:id="@+id/bn_send"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="0.2"            android:text="发送" />    </LinearLayout></RelativeLayout>

//MainActivity.xml 实现登陆注册界面
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="@mipmap/ic_launcher"    > <LinearLayout     android:orientation="vertical"     android:layout_marginTop="600px"     android:layout_width="match_parent"     android:layout_height="wrap_content">    <EditText        android:id="@+id/et_name"        android:layout_width="600px"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:hint="用户名" />    <EditText        android:id="@+id/et_psw"        android:layout_width="600px"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:hint="密 码" /><RelativeLayout    android:layout_width="600px"    android:layout_gravity="center_horizontal"    android:orientation="horizontal"    android:layout_height="wrap_content">    <Button        android:id="@+id/bn_login"        android:layout_toLeftOf="@id/et_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="登陆" />    <Button        android:id="@+id/bn_register"        android:layout_alignParentRight="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="一键注册"/>    <TextView        android:layout_below="@id/bn_login"        android:layout_alignParentRight="true"        android:padding="20px"        android:id="@+id/tv_log"        android:layout_width="6000px"        android:layout_height="wrap_content"        android:minHeight="600px"        android:background="#bf696969"        android:text="等待服务器回应..."        android:textColor="#696969"        android:textSize="30px" /></RelativeLayout> </LinearLayout></RelativeLayout>

//diy_id.xml 添加id的xml文件
<?xml version="1.0" encoding="utf-8"?> <resources>    <item name="LL_listfooterview" type="id" /></resources>

最后吐槽一句:csdn每次点开固定两个广告,能不能换换风格,还有这个 编辑器比较难用,字体大小颜色说变就变。。不知咋回事。


 
忘了php
//login.php
<?php$LGN_IN_RGST = $_GET['a_lgninout'];//denglu-IN OR zhuce-RGST$name = $_GET['a_name'];$psw = $_GET['a_psw']; $con = mysqli_connect("localhost","root","","testlogin");if (!$con){//die('Could not connect: ' . mysqli_error($con));die ('ERROR&服务器连接失败 请重试');} else{if($LGN_IN_RGST == "IN"){//INmysqli_query($con,'set names utf8');$sql = "select * from users WHERE name = '$name'";$result = mysqli_query($con,$sql);//name 查询不存在if(!$result){die ('ERROR&此用户名没有注册');}$row = mysqli_fetch_array($result,MYSQLI_BOTH);//比较 name对应的 pswif($psw == $row[2]){echo 'OK&LOGINOK';}else{die('ERROR&密码不正确'); }}//IN -end////else{//RGST//获取最新的一条数据的 umID$sql = "select max(id) from users";$result = mysqli_query($con,$sql);$row = mysqli_fetch_array($result,MYSQLI_BOTH);$MaxId = $row[0];//zuixin//$name 附上当前id,使其独一无二$name = $name.''.$MaxId;mysqli_query($con,'set names utf8');$sql = "INSERT INTO users(name, psw) VALUES ('$name','$psw')";if (!mysqli_query($con,$sql)){die('ERROR&注册失败 请联系管理员');}else{//返回OK和最大ID,更新用户名控件值echo 'OK&'."$name";}}//RGST -end}mysqli_close($con);?>
//write.php
<?php $con = mysqli_connect("localhost","root","","testlogin");if (!$con){die('Could not connect: ' . mysqli_error($con));} $wrtORrd = $_GET['a_wORr'];if($wrtORrd == 'write') //WRITE{$comment = $_GET['a_comment'];$user = $_GET['a_user'];$time = $_GET['a_time']; mysqli_query($con,'set names utf8');$sql = "INSERT INTO usercomment(User, Comment, Time) VALUES ('$user','$comment', '$time')";if (!mysqli_query($con,$sql)){die('Error: '.mysqli_error($con));}else{echo 'WOK';}}else if($wrtORrd == 'read') //READ{ $NowId = $_GET['a_nowid'];//获取多少条数据mysqli_query($con,'set names utf8');//获取最新的一条数据的 umID$sql = "select max(umID) from usercomment";$result = mysqli_query($con,$sql);$row = mysqli_fetch_array($result,MYSQLI_BOTH);$MaxId = $row[0];//zuixin//echo "MaxId =$MaxId";//【MaxId】越界判断//umID没有第0条数据$min = $MaxId-$NowId+1;//NowId 条数据if($min <= 0){$min = 0;}mysqli_query($con,'set names utf8');$sqlr = "SELECT * FROM usercommentWHERE umID>=$min AND umID<=$MaxId";$result = mysqli_query($con,$sqlr);//echo 'OK';while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){ //echo $row["User"].'+'.$row["Comment"].'+'.$row["Time"];//echo '<br>'; echo urlencode($row["User"]).'&'.urlencode($row["Comment"]).'&'.urlencode($row["Time"]).'/';//echo '<br>'; }echo 'ROK';//读取结束}else{echo 'wrtOrrdERROR';}mysqli_close($con);function characet($data){if( !empty($data) ){    $fileType = mb_detect_encoding($data , array('UTF-8','GBK','LATIN1','BIG5')) ;           if( $fileType != 'UTF-8'){          $data = mb_convert_encoding($data ,'utf-8' , $fileType);           }   }   return $data;    }?>

大概思路:
androi端 点击 一键注册 按钮,由android端自动生成【用户名】【密码】,经编码后,调用GET方法向write.php传递编码后包含数据的url,write.php收到来自Android端请求,开始解析url,然后对应选择 相应语句,发送指令到mysql,要求增加一条表单数据同时将来自android端的【用户名】【密码】发送到mysql;mysql收到来自php的请求,做出反应,向对应表单中增加了一条来自android端的【用户名】【密码】数据,然后返回php,php收到mysql的返回值,判断处理后,再向android端发送返回值,android就收到来自php的反馈信息,处理判断是否操作成功。
写了大段话,按了个靠右快捷键ctrl R 居然被刷新,!!!为何不设置个提示,刷新会清空当前所写的????csdn感觉不好啊,刚开始记录代码生涯,若有不妥之处还请告知1176222373@qq.com



















0 0
原创粉丝点击