之前用第三方框架Okhttp3进行网络测试,在完全遵循官方文档的情况下,做出来的示例不是闪退就是获取不到服务器的数据,最后终于能收到服务器的数据了,却发现服务器收不到POST过去的参数(GET方法当然可以)并且在获取数据时必须用异步回调,让我实在怀疑这个开源项目的可靠性(也可能是官方文档没看懂),最终放弃了这个框架。所以目前使用Java原生的HttpURLConnection构建网络请求框架。(Okhttp的github地址:https://github.com/square/okhttp 头铁的可以尽情尝试:D)
HttpURLConnection可以说还是比较主流的框架(国内的API服务商的示例代码都是用的这个),网上关于此的二次封装也很多,这次使用原生的官方包进行开发。
public class NetThread extends Thread {
private String url;
private String paraname;
private String paracode;
private String Result;
public NetThread(String u,String paran,String parac) {
this.url=u;
this.paraname=paran;
this.paracode=parac;
}
}
首先创建一个网络线程类继承Thread线程类,3个变量分别为
url:请求地址
paraname:参数名
paracode:参数内容
Result:保存请求结果
其实这里参数的变量应该用List或者ArrayList类,因为参数可能不止一个,这里为了初次测试只用一个参数。
接下来是get方法内容,此方法主要实现从目标服务器中取得资源,首先创建一个URL对象,在传入时需要对地址和参数进行组装 格式:地址?参数1=内容1&参数2=内容2 这里略过
URL urls=new URL(url);
HttpURLConnection conn=(HttpURLConnection) urls.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(4000);
初始化之后创建http连接,设置Request方法为GET,设置超时时间4秒。
BufferedReader bfread=new BufferedReader(new InputStreamReader(conn.getInputStream()));
String str;StringBuffer resb=new StringBuffer();
while ((str=bfread.readLine())!=null){
resb.append(str);
}
Glo.getres=resb.toString();
接着进行流式读取,把结果存在一个类型为BufferedReader类型的对象中,接着用字符串按行读取,将结果依次存在StringBuffer中,然后用toString()获取字符串存在Glo.getres中,getres是Glo类中的一个静态变量,用于存储全局数据。Url初始化以及流式读取需要抛出异常,所以包在try catch模块中。最后重载父类的run方法,将此获取数据的方法放在run方法中执行。
Activity界面中,无视其他代码,重点看Button的onClick中的代码:
NetThread t=new NetThread("http://www.cycycd.com/java","name","cy");
t.start();
首先创建一个NetThread对象,并调用有参构造进行构造,然后调用start方法开启线程。在线程运行完毕之后,Glo.getres中已经保存了获取的数据,之后调用写的freview进行界面更新。下面是freview方法的实现:(UI必须在UI线程中更新,不然有可能导致闪退)
void freview(final TextView t, final String v){
runOnUiThread(new Runnable() {
@Override
public void run() {
t.setText(v);
}
});
}
但是这样会产生一个问题:获取网络结果的线程和更新UI的线程是同时进行的,往往UI线程已经执行完毕,网络线程还没有执行完毕,导致全局变量Glo.getres的值在获取服务器结果之前就已经被用来更新UI,解决这个问题的方法是为freview新开一个线程,并加入线程开始条件t.join(),即在网络线程t结束之后再开始执行线程内的freview方法,这样可以保证数据正常更新。贴出源码:
new Thread(new Runnable() {
@Override
public void run() {
NetThread t=new NetThread("http://www.cycycd.com/java","name","cy");
t.start();
try { t.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
freview(restext,Glo.getres);
}}).start();
用PHP写一个简单的服务端测试一下:
<?php
$name=$_GET['name'];
if(empty($name)){
echo "没有参数!";
}
else{
echo "Your name is ".$name;
}
?>
移动端测试:
本次没有测试其它功能,并且参数是提前写好的,所以只需要点击“获取结果GET”就可以从服务端获取数据了。
本文转自本人博客2017年9月11日的文章 以后所有东西都会发在简书
网友评论