文章标题

来源:互联网 发布:知乎怎么推送到kindle 编辑:程序博客网 时间:2024/06/06 03:23

Android入门学习:简单的联网app编写

在上次学习了Android的基本开发环境搭建、基本GUI编写之后,最近开始做移动互联的大作业了。这里记录下自己的学习历程,包括以下内容:

  • 访问网站获取资源
  • 在子线程中更新ui

访问网站获取资源

访问网站的方法我用的是最基础的HttpURLConnection。访问中要设置以下参数:
URL,访问方式(POST,GET),时间限制,请求头部,是否进行输入输出操作
以下操作皆以json数据类型为对象。

 public void JsonPost(final String path, final JSONObject json) {        new Thread(new Runnable() {            @Override            public void run() {                OutputStream os = null;                BufferedReader in = null;                String result = "";                try {                    URL url = new URL(path);                    String content = String.valueOf(json);                    HttpURLConnection conn = (HttpURLConnection)                                      url.openConnection();                    conn.setConnectTimeout(5000);//设置超时时间                    conn.setDoOutput(true);                    conn.setRequestMethod("POST");                    conn.setRequestProperty("Content-Type", "application/json");//设置请求头部,一般用于身份验证什么的                    os = conn.getOutputStream();                    os.write(content.getBytes("utf-8"));                    os.flush();                    in = new BufferedReader(                            new InputStreamReader(conn.getInputStream()));                    String line;                    if (conn.getResponseCode() == 200) {                        while ((line = in.readLine()) != null) {                            result += line;//结果存于result中以String保存                        }                    }                } catch (SocketTimeoutException e) {                    e.printStackTrace();                } catch (MalformedURLException e) {                    e.printStackTrace();                } catch (ProtocolException e) {                    e.printStackTrace();                } catch (IOException e) {                    e.printStackTrace();                }                finally {                    try {                        if (os != null) {                            os.close();                        }                        if (in != null) {                            in.close();                        }                    } catch (IOException ex) {                        ex.printStackTrace();                    }                }                Message ms=new Message();                ms.obj=result;                handler.sendMessage(ms);            }        }).start();    }

这里将访问网站的地址,需要传入的json作为参数(必须都标注为final否则报错),通过 HttpURLConnection conn = (HttpURLConnection) url.openConnection();打开连接,由于这里是POST传入参数,故要加一句conn.setDoOutput(true);,这样边允许向内传入参数。访问网站的整个过程都需要在一个子线程内执行。
还有别忘了建立完子线程要启动,一开始忘了加start()半天没反应。。

下面是GET方法的例子,添加了更多的请求头部:

public void getGroup(final String path,final String token) {        new Thread(new Runnable() {            @Override            public void run() {                String  base64Token = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);                OutputStream os = null;                BufferedReader in = null;                String result = "";                try {                    URL url = new URL(path);                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();                    conn.setConnectTimeout(5000);                    conn.setDoOutput(false);                   // conn.setDoInput(true);                    conn.setRequestMethod("GET");                  //  conn.setRequestProperty("Content-Type", "application/json");                    String auth="Basic"+" "+base64Token;                    conn.setRequestProperty("Authorization",auth);                    conn.setRequestProperty("Charset", "UTF-8");                    Log.d("token",auth);                    in = new BufferedReader(                            new InputStreamReader(conn.getInputStream()));                    String line;                    if (conn.getResponseCode() == 200) {                        while ((line = in.readLine()) != null) {                            result += line;                        }                    }                } catch (SocketTimeoutException e) {                    e.printStackTrace();                } catch (MalformedURLException e) {                    e.printStackTrace();                } catch (ProtocolException e) {                    e.printStackTrace();                } catch (IOException e) {                    e.printStackTrace();                }                finally {                    try {                        if (os != null) {                            os.close();                        }                        if (in != null) {                            in.close();                        }                    } catch (IOException ex) {                        ex.printStackTrace();                    }                }                Message ms=new Message();                ms.obj=result;                handler.sendMessage(ms);            }        }).start();    }

这里与前面不同的是,由于是GET方法,必须加一句conn.setDoOutput(false);,否则即使设置为GET方法也会成为POST,调用会出现java.io.filenotfoundexception错误。

在子线程中更新ui

如果在子线程里直接根据网站返回的信息更新UI,APP会直接崩溃,这是因为子线程是不被允许更改UI控件的,只有主线程才行,这里我用的是添加一个Handle,他是属于主线程的一部分故不会出现上面的问题。

  private Handler handler=new Handler(){            public void handleMessage(Message message){                text.setText((String)message.obj);            }        };

在子线程中调用:

   Message ms=new Message();   ms.obj=result;   handler.sendMessage(ms);

这里通过message.obj属性将字符串result传入,然后在handle内再取出转换类型。
注意传入时用sendMessage,处理是用handleMessage,一开始没注意两个都用handleMessage,然后就报错了。。
附上最后效果
这里写图片描述