Android网络编程
安装查看源码的软件httpwatch(这里就没安装了)
在浏览器中按快捷键shift+F2 调用httpwatch
//创建URL对象,指定我们要访问的网址路径
URL url = new URL(path);
//拿到HttpURLConnection对象,用于发送或者接收数据extends URLConnection
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置发送get请求
conn.setRequestMethod("GET");//get需要大写,默认就是get,也可以不写此行
//设置请求超时时间
conn.setConnectTimeout(5000);//5秒
//获取服务器返回的状态码
int code = conn.getResponseCode();
if(code == 200){
//获取服务器返回的数值,是以流的形式返回的,把流转换为字符串是一种常见的操作,因此将其设置为一个utils
InputStream in = conn.getInputStream();
//使用我们定义的工具类,把InputStream转为String
String content = StreamToString.readStream(in);
//把流里面的数据显示在textView上
tv_content.setText(content);
//需要加上权限:android.permission.INTERNET
控件ScrollView里面只能包含一个孩子
二、消息机制的写法(重点)
**规则:**1、不管是什么版本的手机,只要做耗时的操作(比如连接网络,拷贝大的数据,Thread.sleep()等)就自己开一个子线程;2、获取数据后想要更新UI,就使用Handler就可以了。
1、相关概念1、anr Application not response 应用无响应 主线程(UI线程)
2、如果在主线程中进行了耗时的操作(比如连接网络 拷贝大的数据,Thread.sleep()等)
3、为了避免anr,可以把耗时的操作放到子线程中(自己创建一个子线程)
4、在4.0之后,谷歌强制要求连接网络不能在主线程进行访问
所以创建一个子线程
// 创建一个子线程
new Thread() {
public void run() {
...内容
};
}.start();
也可以在ACtivity的onCreate()方法中加入这样一段代码,适用于网络请求数据量很小的,如下
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
04-10 02:01:57.297: W/System.err(789): android.os.NetworkOnMainThreadException
5、只有主线程(UI线程)才可以更新UI
所以定义一个Handler
04-10 02:28:07.306: W/System.err(1392): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
2、Handler的使用
protected static final int REQUESTSUCCESS = 0;// ctrl+shift+x 大写 y:小写
//定义一个Handler,重写其中的handleMessage方法
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
String content = (String) msg.obj;//获取msg中的数据
tv_content.setText(content);//在主线程中更新UI,将获得的数据显示在控件上
};
};
//创建message对象
Message msg = new Message();//或者使用 Message.obtain()方法获得Message对象;
msg.what = REQUESTSUCCESS;// 给这个消息指定一个标识,代表是哪条消息,为int类型
msg.obj = content;//把数据放到msg中
//拿着我们创建的handler,告诉系统,我们要更新UI
handler.sendMessage(msg);//发送消息,相应的handleMessage这个方法就会执行
3、消息机制的原理
Handler的作用是用来发消息和处理消息的
Looper的作用是去消息队列(messagequeue)里面取消息,交给handler中的handleMessage方法处理
Looper在主线程创建的时候,就有了
4、cache和file目录
cache:cache存放缓存的临时数据。
file:file中存放重要数据。
四、runOnUiThread的写法 如果仅仅是更新ui,那么就用runOnUiThread这个api就可以 有的时候需要通过Handler发送消息,携带数据,这时候必须使用HandlerrunOnUiThread(new Runnable() {
public void run() { //该run()方法是谷歌工程师封装好的,可以在其中更新ui
iv.setImageBitmap(bitmap);
Toast.makeText(getApplicationContext(),"查看图片成功", 0).show();
}
});
五、Handler中的api
类似java基础中的Timer
// 5秒后执行run(),这个run()是谷歌封装好的方法,可以更新UI
new Handler().postDelayed(new Runnable() {
public void run() {
System.out.println("哈哈哈");
tv.setText("哈哈哈哈哈啊,I am coming home!");
}
}, 5000);
// java基础中的timer(定时器)方法,该方法三秒后,每隔三秒执行一次这个方法
// 这个run()方法相当于子线程,不能更新UI,所以要加上runOnUiThread方法
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("嘿嘿嘿"); //打印出log
runOnUiThread(new Runnable() {
public void run() {
tv.setText("嘿嘿嘿,I am coming home!");//更新ui
}
});
}
};
timer.schedule(task, 3000, 3000);
}
六、案例:新闻客户端
1、安装tomcat
//启动tomcat
1、先在cmd下的/bin目录下 service.bat install
2、点击bin目录下的tomcat8w.exe,开启tomcat//如果点击tomcat8w.exe闪现则执行第一条,否则忽略第一条
//测试tomcat是否安装成功
http://localhost:8080 //如何出现小猫图案则安装成功
//在tomcat的ROOT目录下加入内容,即可通过网址访问,本地的服务器
D:\tomcat\apache-tomcat-8.5.43\webapps\ROOT
//localhost表示本地的服务器
http://localhost/baby.jpg
//192.168.1.104本机ip地址
http://192.168.1.104:8080/baby.jpg
http://192.168.1.104:8080/QQScLauncher.exe
2、写新闻客户端
包含的知识点:HttpURLConnection,ListView,BaseAdapter,inflate,xml的解析,bitmap,runOnUiThread等。
ui效果是公司里面的美工画的
应用的传输数据,定义接口
关于xml的数据,是服务器的开发人员通过一定的技术手段返回的,对应android开发人员我们要会解析就OK,把我们关心的数据取出来,展示到android的空间上
3、smartimageview(1)首先把com源码包复制到当前工程
(2)然后在布局文件中定义此控件时一定是这个类的完整包名+类名,如
(3)最后可以直接调用图片地址图片:
iv_icon.setImageUrl(iconUrl);
4、自定义smartimageview
参考网站github
七、三种提交数据到服务器的方式 1、使用HttpURLConnection方式把数据提交到服务器基于http协议
get方式:组拼url地址把数据组拼到url上,有大小限制 1kb(浏览器规定) 4kb(http协议规定)
post方式:post方式提交安全,没有大小限制。要自己组拼请求正文。请求头信息
get方式提交数据代码如下
//使用HttpURLConnection GET方式提交数据
public static String loginByGet(String username, String password) {
try {
//拼装URL 注意为了防止乱码 这里需要将参数进行编码 http://192.168.1.104:8080
String path = "http://192.168.1.104:8080/Web/LoginServlet?username="
+ URLEncoder.encode(username,"UTF-8")
+ "&password="
+ URLEncoder.encode(password,"UTF-8");
//创建URL实例
URL url = new URL(path);
//获取HttpURLConnection对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000); //设置超时时间
conn.setRequestMethod("GET"); //设置访问方式
int code = conn.getResponseCode(); //拿到返回的状态码
if (code == 200) { // 请求成功
InputStream is = conn.getInputStream();
String text = StreamTools.readInputStream(is);
return text;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
post方式提交数据代码如下
//使用HttpURLConnection POST方式提交数据
public static String loginByPost(String username, String password) {
try {
//要访问的资源路径
String path = "http://192.168.1.104:8080/Web/LoginServlet";
//创建URL的实例
URL url = new URL(path);
//获取HttpURLConnection对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置超时时间
conn.setConnectTimeout(5000);
//指定请求方式
conn.setRequestMethod("POST");
//准备数据 将参数编码
String data = "username=" + URLEncoder.encode(username,"UTF-8")
+ "&password=" + URLEncoder.encode(password,"UTF-8");
//设置请求头
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", data.length() + "");
//将数据写给服务器
conn.setDoOutput(true);
//得到输出流
OutputStream os = conn.getOutputStream();
os.write(data.getBytes()); //将数据写入输出流中
int code = conn.getResponseCode(); //那到服务器返回的状态码
if (code == 200) {
//得到服务器返回的输入流
InputStream is = conn.getInputStream();
//将输入流转换成字符串
String text = StreamTools.readInputStream(is);
return text;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
2、接口HttpClient
实现get和post提交数据
get
// 采用httpclient get提交数据
public static String loginByClientGet(String username, String password) {
try {
//1 、创建HttpClient对象
HttpClient client = new DefaultHttpClient();
//2、拼装路径,注意将参数编码
String path = "http://192.168.1.104:8080/Web/LoginServlet?username="
+ URLEncoder.encode(username,"UTF-8")
+ "&password="
+ URLEncoder.encode(password,"UTF-8");
//3、GET方式请求
HttpGet httpGet = new HttpGet(path);
//4、拿到服务器返回的HttpResponse对象
HttpResponse response = client.execute(httpGet);
//5、拿到状态码
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
//获取输入流
InputStream is = response.getEntity().getContent();
//将输入流转换成字符串
String text = StreamTools.readInputStream(is);
return text;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
post
//采用httpclient post提交数据
public static String loginByClientPost(String username, String password) {
try {
//1、获取HttpClient对象
HttpClient client = new DefaultHttpClient();
//2、指定访问地址
String path = "http://192.168.1.104:8080/Web/LoginServlet";
//3、POST方式请求网络
HttpPost httpPost = new HttpPost(path);
//4、指定要提交的数据实体
//准备parameters,列表
List parameters = new ArrayList();
//准备NameValuePair,实际上就是我们要提交的用户名,密码;key-values
BasicNameValuePair nameValuePair = new BasicNameValuePair("username", username);
BasicNameValuePair pwdValuePair = new BasicNameValuePair("password", password);
//把nameValuePair和pwdValuePair加入到集合中
parameters.add(nameValuePair);
parameters.add(pwdValuePair);
//准备entity
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters);
//准备post方式提交的正文,以实体形式准备(键值对形式)
httpPost.setEntity(entity);
//5、请求服务器并拿到服务器返回的信息
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode(); //拿到状态码
if (code == 200) { //访问成功
InputStream is = response.getEntity().getContent();
//将输入流转换成字符串
String text = StreamTools.readInputStream(is);
return text;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
3、使用开源项目AsyncHttpClient
//实现get和post提交数据:参见github网站
总结:3种方式提交数据到服务器
1、HttpURLConnection
Range,使用请求头不能用封装的开源代码使用时就用这个方式
2、HttpClient(了解,没有人用)
3、AsyncHttpClient
使用方便,但是是已经封装好的
八、多线程下载javase多线程下载AsyncHttpClient
1、多线程下载原理
原创文章 6获赞 6访问量 961
关注
私信
展开阅读全文
作者:名侦探柯小启
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341