1.网络图片查看器
网络图片查看器
1.获取输入的URL地址,判断是否为空
2.建立子线程,获取URl对象new URL(path)
3.打开连接获取HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
4.设置连接超时时间conn.setConnectionTimeOut(5000)毫秒
5.设置请求方式setRequestMethod
GET或者POST要大写
6.获取响应码 conn.getResponseCode()
7.判断是不是200,是200就一切正常
8.获取conn.getInputStream() ,
9.使用BitmapFactory.decode(in),将流转换为Bitmap对象
10.使用Message msg = Message.obtain(),
11.设置msg.what是int 类型用来表示标识
符如SUCCESS,ERROR 与msg.obj为Object类型msg.obj=bitmap,用来传递数据
12.handler.sendMessage(msg)发送给主线程的Handler对象
13.主线程中Handler handler = newHandler(){
重写handleMessage方法 判断msg.what,做主线程中的UI更新或者提示用户错误信息}
14.添加网络权限Internet
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!--输入URL图片地址 -->
<EditText
android:id="@+id/et_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="http://188.188.3.79:8080/itest/test.png"
/>
<Button
android:onClick="display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示图片"/>
<ImageView
android:id="@+id/iv_show"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout> |
Activity
* 网络图片查看器
* 1.获取输入的URL地址,判断是否为空
* 2.建立子线程,获取URl对象new URL(path)
* 3.打开连接获取HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
* 4.设置连接超时时间conn.setConnectionTimeOut(5000)毫秒
* 5.设置请求方式setRequestMethod
* GET或者POST要大写
* 6.获取响应码 conn.getResponseCode()
* 7.判断是不是200,是200就一切正常
* 8.获取conn.getInputStream() ,
* 9.使用BitmapFactory.decode(in),将流转换为Bitmap对象
* 10.使用Message msg = Message.obtain(),
* 11.设置msg.what是int 类型用来表示标识
* 符如SUCCESS,ERROR 与msg.obj为Object类型msg.obj=bitmap,用来传递数据
* 12.handler.sendMessage(msg)发送给主线程的Handler对象
* 13.主线程中Handler handler = newHandler(){
* 重写handleMessage方法 判断msg.what,做主线程中的UI更新或者提示用户错误信息
* }
* 14.添加网络权限Internet
public class MainActivity extends Activity {
* 标识 常量
protected static final int ERROR = 0;
protected static final int SUCCESS = 1;
* 用户输入的url地址
private EditText et_path;
* 显示图片
private ImageView iv_show;
* Handler 处理
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
* 用户输入的url地址
et_path = (EditText) findViewById(R.id.et_path);
* 显示图片
iv_show = (ImageView) findViewById(R.id.iv_show);
* 13.主线程中Handler handler = newHandler(){
* 重写handleMessage方法 判断msg.what,做主线程中的UI更新或者提示用户错误信息
* }
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
iv_show.setImageBitmap((Bitmap)msg.obj);
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络连接超里",
Toast.LENGTH_SHORT).show();
break;
}
}
};
}
* 显示图片的按键 获取用户输入的URL, 并显示在下方
* @param v
* 按键display
public void display(View v) {
// *1.获取输入的URL地址,判断是否为空
final String path = et_path.getText().toString().trim();
if(TextUtils.isEmpty(path)){
Toast.makeText(this, "输入的url路径不能为空",
Toast.LENGTH_SHORT).show();
return ;
}
// * 2.建立子线程,获取URl对象new URL(path)
new Thread(new Runnable() {
@Override
public void run() {
try {
// * 3.打开连接获取HttpURLConnection conn = (HttpURLConnection)
URL url = new URL(path);
// url.openConnection();
HttpURLConnection conn= (HttpURLConnection)
url.openConnection();
// * 4.设置连接超时时间conn.setConnectionTimeOut(5000)毫秒
conn.setConnectTimeout(5000);
// * 5.设置请求方式setRequestMethod GET或者POST要大写
conn.setRequestMethod("GET");
// * 6.获取响应码 conn.getResponseCode()
int code = conn.getResponseCode();
// * 7.判断是不是200,是200就一切正常
if(code==200){
// * 8.获取conn.getInputStream() ,
InputStream in = conn.getInputStream();
// * 9.使用BitmapFactory.decodeStream(in),将流转换为Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(in);
// * 10.使用Message msg = Message.obtain(),
Message msg = Message.obtain();
// * 11.设置msg.what是int 类型用来表示标识 符如SUCCESS,ERROR
msg.what=SUCCESS;
// 与msg.obj为Object类型msg.obj=bitmap,用来传递数据
msg.obj=bitmap;
// * 12.handler.sendMessage(msg)发送给主线程的Handler对象
handler.sendMessage(msg);
}else{
sendError();
}
} catch (MalformedURLException e) {
e.printStackTrace();
sendError();
} catch (ProtocolException e) {
e.printStackTrace();
sendError();
} catch (IOException e) {
e.printStackTrace();
sendError();
}
}
private void sendError() {
Message msg = Message.obtain();
// * 11.设置msg.what是int 类型用来表示标识 符如SUCCESS,ERROR
msg.what=ERROR;
// * 12.handler.sendMessage(msg)发送给主线程的Handler对象
handler.sendMessage(msg);
}
}).start();
}
} |
添加网络权限
<uses-permission android:name="android.permission.INTERNET"/> |
2.HTMLView查看
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--
用户输入的URL -->
<EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="http://188.188.3.79:8080/"/>
<Button
android:id="@+id/btn_show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 显示结果 -->
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</ScrollView>
</LinearLayout> |
流转换工具类
* 将流转换为字符的工具类
public class StreamUtils {
public static String decode(InputStream in)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len =0;
byte [] buf = new byte[1024];
while((len=in.read(buf))!=-1){
baos.write(buf, 0, len);
}
in.close();
baos.close();
return baos.toString();
}
} |
Activitty
* HTML查看器
* 步骤:
* 1.获取用户输入的url
* 2.判断是否为空
* 3.建立子线程
* 4.建立url对象
* 5. 建立HttpURLConnection连接
* 6.设置请求方式,与连接超时
* 7.获取响应码
* 8.判断是否为200
* 9.获取输入流
* 10.解析为字符串
* 11.handler发送message
* 12.主线程中的Handler做更新UI的操作
public class MainActivity extends Activity implements
OnClickListener {
protected static final int ERROR = 0;
protected static final int SUCCESS = 1;
* 用户输入的URL
private EditText et_path;
* 输入完成后点击的按键
private Button btn_show;
* 结果显示
private TextView tv_result;
* 消息处理
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
* 用户输入的URL
et_path = (EditText) findViewById(R.id.et_path);
* 输入完成后点击的按键
btn_show = (Button) findViewById(R.id.btn_show);
btn_show.setOnClickListener(this);
* 结果显示
tv_result = (TextView) findViewById(R.id.tv_result);
* 消息处理
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//判断msg.what
switch (msg.what) {
case SUCCESS:
//成功就处理数据
tv_result.setText(msg.obj.toString());
break;
case ERROR:
//失败就提示用户失败
Toast.makeText(MainActivity.this, "网络连接超时",
Toast.LENGTH_SHORT).show();
break;
}
}
};
}
* 单击事件监听器
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_show:
display();
break;
}
}
* 显示图片的方法单击事件
private void display() {
//1.获取用户输入的url
final String path = et_path.getText().toString().trim();
//2.判断是否为空
if(TextUtils.isEmpty(path)){
Toast.makeText(this, "url不能为空", Toast.LENGTH_SHORT).show();
return;
}
//3.建立子线程
new Thread(new Runnable() {
@Override
public void run() {
try {
//4.建立url对象
URL url = new URL(path);
//5. 建立HttpURLConnection连接
HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
//6.设置请求方式,与连接超时
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
//7.获取响应码
int code = conn.getResponseCode();
//8.判断是否为200
if(code==200){
//9.获取输入流
InputStream in = conn.getInputStream();
//10.解析为字符串
String data = StreamUtils.decode(in);
//是200表示成功 设置成功消息
Message msg = Message.obtain();
//设置成功标识
msg.what=SUCCESS;
//传递数据
msg.obj=data;
//发送消息
handler.sendMessage(msg);
}else{
//发送错误消息
sendError();
}
} catch (MalformedURLException e) {
e.printStackTrace();
//发送错误消息
sendError();
} catch (IOException e) {
e.printStackTrace();
//发送错误消息
sendError();
}
}
private void sendError() {
//错误发送错误消息
Message msg = Message.obtain();
//设置错误标识
msg.what=ERROR;
//发送消息
handler.sendMessage(msg);
}
} ).start();
}
} |
添加网络权限
<uses-permission android:name="android.permission.INTERNET"/> |
3.ANR现象:
Anr( application not responding) ---- 应用程序无响应
如果 点击了 某个按钮 ,按钮背后干了比较耗时的事儿 , 长时间的没有相应, 并且这个长时间的事儿是运行在主线程的
那么就 会出现ANR现象.
主线程中不能干 耗时的事儿, 主线程不能够被阻塞.
4. 手机号码吉凶测试(xml数据的解析):
实体类
* 解析XML封装的JAVABEAN
* <phones>
<phone type="huawei">
<phoneNum>13410110407</phoneNum>
<address>广东深圳移动</address>
<phoneJx>大凶之兆,多多拜神</phoneJx>
</phone>
</phones> |
public class Phone {
* 手机类型
private String type;
* 手机 号码
private String phoneNum;
* 归属地
private String address;
* 手机号吉凶
private String phoneJx;
* Getter与Setter方法
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneJx() {
return phoneJx;
}
public void setPhoneJx(String phoneJx) {
this.phoneJx = phoneJx;
}
public String show(){
return "手机号码:"+this.phoneNum+",手机类型:"+this.type+",归属地:"+this.address+",手机号吉凶";
}
} |
工具类
* XML流解析工具类
public class StreamUtils {
* 获取URLConnection的InputStream
* @param in 输入流
* @return 返回一个phone对象
public static Phone decode(InputStream in){
Phone p = new Phone();
try {
XmlPullParser pullParser = Xml.newPullParser();
pullParser.setInput(in,"UTF-8");
int eventType = pullParser.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_TAG){
if("phone".equals(pullParser.getName())){
String type = pullParser.getAttributeValue(null,
"type");
p.setType(type);
}else if("phoneNum".equals(pullParser.getName())){
String phoneNum = pullParser.nextText();
p.setPhoneNum(phoneNum);
}else if("address".equals(pullParser.getName())){
String address = pullParser.nextText();
p.setAddress(address);
}else if("phoneJx".equals(pullParser.getName())){
String phoneJx = pullParser.nextText();
p.setPhoneJx(phoneJx);
}
}
eventType=pullParser.next();
}
in.close();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return p;
}
} |
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--用户输入的URL -->
<EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入URL"
android:text="http://188.188.3.79:8080/itest/phone.xml"/>
<!-- 发送-->
<Button
android:onClick="send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请求"/>
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout> |
Activity
* 网络请求XML
1.获取用户输入的URL地址
2.判断用户输入是否为空,为空就提示用户
3.不为空就创建子线程
4.创建URL对象new
* URL(paht)
5.url.openConnection();
* 6.设置请求方法setRequestMethod("GET"),设置连接超时时间setConnectTimeOut(5000)
* 7.获取响应码,判断是否为200,不为200就使用handler发送Error的message
* 8.是200,就获取输入流conn.getInputStream()
9.使用Xml.PullParse解析xml,并封装为对象,返回一个对象
* 10.使用handler发送message,messag.what=SUCCESS,message.obj=封装的对象
* 11.主线程handler重写handlMessage方法,判断msg.what 执行更新UI信息或者提示用户错误信息
public class MainActivity extends Activity {
* 标识符常量
protected static final int SUCCESS = 0;
protected static final int ERROR = 1;
* 用户输入的URL
private EditText et_path;
* 显示结果
private TextView tv_result;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
tv_result = (TextView) findViewById(R.id.tv_result);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 11.主线程handler重写handlMessage方法,判断msg.what
执行更新UI信息或者提示用户错误信息
switch (msg.what) {
case SUCCESS:
Phone phone = (Phone) msg.obj;
tv_result.setText(phone.show());
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络异常",
Toast.LENGTH_SHORT).show();
break;
}
}
};
}
* 发送用户输入的URL,获取XML数据
* @param v
public void send(View v) {
// 1.获取用户输入的URL地址
final String path = et_path.getText().toString().trim();
// 2.判断用户输入是否为空,为空就提示用户
if (TextUtils.isEmpty(path)) {
Toast.makeText(this, "url地址不能为空",
Toast.LENGTH_SHORT).show();
return;
}
// 3.不为空就创建子线程
new Thread(new Runnable() {
@Override
public void run() {
try {
// 4.创建URL对象new URL(path)
URL url = new URL(path);
// 5.url.openConnection();
HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
// 6.设置请求方法setRequestMethod("GET"),设置连接超时时间setConnectTimeOut(5000)
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// 7.获取响应码,判断是否为200,不为200就使用handler发送Error的message
int code = conn.getResponseCode();
if(code==200){
// 8.是200,就获取输入流conn.getInputStream()
InputStream in = conn.getInputStream();
// 9.使用Xml.PullParse解析xml,并封装为对象,返回一个对象
Phone phone = StreamUtils.decode(in);
// 10.使用handler发送message,messag.what=SUCCESS,message.obj=封装的对象
Message msg = Message.obtain();
msg.what=SUCCESS;
msg.obj = phone;
handler.sendMessage(msg);
}else{
//发送错误消息
sendErrorMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
* 发送的消息
private void sendErrorMessage() {
Message msg = Message.obtain();
msg.what=ERROR;
handler.sendMessage(msg);
}
}).start();
}
} |
5.解析JSON
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<EditText
android:id="@+id/et_city"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入要查寻的城名称"/>
<Button
android:onClick="search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询天气"/>
<TextView
android:id="@+id/tv_result"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#ff0000"
android:dividerHeight="2dp">
</ListView>
</LinearLayout>
weather_ithem
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/fengxiang"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/fengli"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/high"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/type"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/low"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout> |
工具类
/**
* 解析流的工具类,
* 把流解析为字符串
public class StreamUtils {
public static String decode(InputStream in)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len =0;
byte [] buff = new byte[1024];
while((len=in.read(buff))!=-1){
baos.write(buff, 0, len);
}
in.close();
baos.close();
return baos.toString();
}
} |
Activity
* 查询天气预报
* 1.获取输入的城市
* 2.判断是否为空
* 3.获取string中的资源与用户输入的拼接为访问的url
* 4.建立HttpURLConnection
* 5.设置请求方式与连接超时时间
* 6.获取响应码
* 7.判断是否为200
* 8.是200就,使用自定义的流工具类,将流转换为字符串
* 9.获取DESC判断是否为OK,分别处理
* 10,是OK,继续使用JSON解析
* 11.将数组发给主线程中的handler做处理
* 12.handler做更新UI或者 提示用户错误信息等
public class MainActivity extends Activity {
protected static final int SUCCESS = 0;
protected static final int INVALID_CITY = 1;
protected static final int ERROR = 2;
private static final String TAG = "R.string.weather";
* 用户输入的城市
private EditText et_city;
* 容器用于显示结果
private ListView lv;
private TextView tv_result;
private BaseAdapter adapter;
* handler
private Handler handler;
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_city = (EditText) findViewById(R.id.et_city);
lv = (ListView) findViewById(R.id.lv);
tv_result = (TextView) findViewById(R.id.tv_result);
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
final JSONArray array =(JSONArray) msg.obj;
//tv_result.setText(array.toString());
adapter = new BaseAdapter() {
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
View view ;
if(convertView==null){
view = View.inflate(MainActivity.this, R.layout.weather_item,
null);
}else{
view = convertView;
}
try {
JSONObject obj = array.getJSONObject(position);
TextView fengxiang =(TextView) view.findViewById(R.id.fengxiang);
fengxiang.setText("风向:"+obj.getString("fengxiang"));
TextView fengli =(TextView) view.findViewById(R.id.fengli);
fengli.setText("风力:"+obj.getString("fengli"));
TextView high =(TextView) view.findViewById(R.id.high);
high.setText("高温:"+obj.getString("high"));
TextView type =(TextView) view.findViewById(R.id.type);
type.setText("天气:"+obj.getString("type"));
TextView low =(TextView) view.findViewById(R.id.low);
low.setText("低温:"+obj.getString("low"));
TextView data =(TextView) view.findViewById(R.id.date);
data.setText("日期:"+obj.getString("data"));
} catch (JSONException e) {
e.printStackTrace();
}
return view;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return array.length();
}
};
dialog.dismiss();
lv.setAdapter(adapter);
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络异常",
Toast.LENGTH_SHORT).show();
break;
case INVALID_CITY:
Toast.makeText(MainActivity.this, "输入的城市
不存在", Toast.LENGTH_SHORT).show();
break;
}
}
};
}
* 查询天气
* @param v 查询按键
public void search(View v){
//获取用户化输入的城市
final String city = et_city.getText().toString().trim();
if(TextUtils.isEmpty(city)){
Toast.makeText(this, "城市不能为空", Toast.LENGTH_SHORT).show();
return;
}
System.out.println(city);
dialog = ProgressDialog.show(MainActivity.this,
"努力加载", "请稍后..........");
new Thread(new Runnable() {
@Override
public void run() {
try {
//请求路径
String path=getResources().getString(R.string.weather);
Log.i(TAG, path);
//建立URL
URL url = new URL(path+URLEncoder.encode(city,
"UTF-8"));
//打开连接
HttpURLConnection conn = (HttpURLConnection)
url.openConnection();
//设置主求方式与连接超时时间
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
//获取响应码
int code = conn.getResponseCode();
//判断是否为成功
if(code==200){
//获取输入流
InputStream in = conn.getInputStream();
String data = StreamUtils.decode(in);
JSONObject dataObj = new JSONObject(data);
String desc = dataObj.getString("desc");
Log.i(TAG, desc);
if("ok".equalsIgnoreCase(desc)){
/**
* {"desc":"OK",
* "status":1000,
* "data":{"wendu":"13","ganmao":"天气较凉,较易发生感冒,请适当增加衣服。体质较弱的朋友尤其应该注意防护。",
* "forecast":
* [{"fengxiang":"无持续风向","fengli":"微风级","high":"高温
15℃","type":"小雨","low":"低温
11℃","date":"23日星期二"},
* {"fengxiang":"无持续风向","fengli":"微风级","high":"高温
15℃","type":"阴","low":"低温
12℃","date":"24日星期三"},
* {"fengxiang":"无持续风向","fengli":"微风级","high":"高温
16℃","type":"小雨","low":"低温
12℃","date":"25日星期四"},
* {"fengxiang":"无持续风向","fengli":"微风级","high":"高温
17℃","type":"阴","low":"低温
13℃","date":"26日星期五"},
* {"fengxiang":"无持续风向","fengli":"微风级","high":"高温
18℃","type":"阴","low":"低温
13℃","date":"27日星期六"}],
* "yesterday":{"fl":"微风","fx":"无持续风向","high":"高温
21℃","type":"多云","low":"低温
16℃","date":"22日星期一"},"aqi":"28","city":"深圳"}}
*/
//获取data:每一天的信息
JSONObject dataJsonObject = dataObj.getJSONObject("data");
//获取一周的数据
JSONArray array = dataJsonObject.getJSONArray("forecast");
Message msg =Message.obtain();
msg.what =SUCCESS;
msg.obj = array;
handler.sendMessage(msg);
}else {
Message msg = Message.obtain();
msg.what= INVALID_CITY;
handler.sendMessage(msg);
}
}else{
//网络异常
sendErrorMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
sendErrorMessage();
//网络异常
} catch (IOException e) {
e.printStackTrace();
//网络异常
sendErrorMessage();
} catch (JSONException e) {
e.printStackTrace();
}
}
//发送错误信息
private void sendErrorMessage() {
Message msg = Message.obtain();
msg.what= ERROR;
handler.sendMessage(msg);
}
}).start();
}
} |
6.模拟新闻客户端
本地tomcat服务器提供一个XML文件与图片
<?xml version="1.0" encoding="UTF-8" ?> <channel> <item> <title>军报评徐才厚</title> <description>人死账不消 反腐步不停,支持,威武,顶,有希望了。 </description> <image>http://192.168.1.104:8080/img/a.jpg</image> <type>1</type> <comment>163</comment> </item> <item> <title>女司机翻车后直奔麻将室</title> <description>女司机翻车后直奔麻将室,称大难不死手气必红 </description> <image>http://192.168.1.104:8080/img/b.jpg</image> <type>2</type> </item> <item> <title>小伙当“男公关”以为陪美女</title> <description>来源:中国青年网,小伙当“男公关”以为陪美女,上工后被大妈吓怕 </description> <image>http://192.168.1.104:8080/img/c.jpg</image> <type>3</type> </item> <item> <title>男子看上女孩背影欲强奸</title> <description> 来源:新京报, 看到正脸后放弃仍被捕 </description> <image>http://192.168.1.104:8080/img/d.jpg</image> <type>1</type> <comment>763</comment> </item> </channel> |
添加权限
<uses-permission android:name="android.permission.INTERNET"/> |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent">
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
//listView使用的
<?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"
>
<!--自定义的控件 -->
<com.itheima.newsclient.smartview.MySmartView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:src="@drawable/ic_launcher"
/>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@id/iv_icon"
android:text="标题" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_below="@id/tv_title"
android:layout_toRightOf="@id/iv_icon"
android:text="内容描述" />
<TextView
android:id="@+id/tv_comm"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_below="@id/tv_desc"
android:text="评论数" />
</RelativeLayout>
|
实体JAVABEAN
/** * 新闻封装类 * <item> <title>军报评徐才厚</title> <description>人死账不消 反腐步不停,支持,威武,顶,有希望了。</description> <image>http://188.188.3.100:8080/img/a.jpg</image> <type>1</type> <comment>163</comment> </item> */ public class NewsItems {
private String title;
private String description;
private String imageUrl;
private String type;
private String comment;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
} |
工具类
/** * 解析XML public class NewsClientService {
public static List<NewsItems> getNewsInfo(InputStream
in) throws XmlPullParserException, IOException
{
List<NewsItems> list = new ArrayList<NewsItems>();
//XML解析器
XmlPullParser pullParser = Xml.newPullParser();
//设置输入编码
pullParser.setInput(in,"UTF-8");
//获取事件
int eventType = pullParser.getEventType();
//开始解析
NewsItems newsItem=null;
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_TAG){
if("item".equals(pullParser.getName())){
//如果是开始就新对象
newsItem = new NewsItems();
}else if("title".equals(pullParser.getName())){
//设置标题
newsItem.setTitle(pullParser.nextText());
}else if("description".equals(pullParser.getName())){
//设置描述内容
newsItem.setDescription(pullParser.nextText());
}else if("image".equals(pullParser.getName())){
//设置image
newsItem.setImageUrl(pullParser.nextText());
}else if("type".equals(pullParser.getName())){
//设置类型
newsItem.setType(pullParser.nextText());
}else if("comment".equals(pullParser.getName())){
//设置评论数
newsItem.setComment(pullParser.nextText());
}
}else if(eventType==XmlPullParser.END_TAG){
if("item".equals(pullParser.getName())){
//添加对象到集合
list.add(newsItem);
}
}
//移动指针
eventType=pullParser.next();
}
return list;
}
} |
自定义的
/** * 自定义显示地址为path的图片 public class MySmartView extends ImageView {
public MySmartView(Context context) {
super(context);
}
public MySmartView(Context context, AttributeSet
attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MySmartView(Context context, AttributeSet
attrs) {
super(context, attrs);
}
* 设置图像
public void setImage(String url){
ViewAsyncTask viewAsyncTask = new ViewAsyncTask(getContext());
try {
viewAsyncTask.execute(new URL(url));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private class ViewAsyncTask extends AsyncTask<URL,
Integer, Bitmap>{
private Context mContext;
public ViewAsyncTask(Context mContext){
this.mContext=mContext;
}
@Override
protected Bitmap doInBackground(URL... params)
{
try {
HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
//设置请求方法
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
if(code==200){
InputStream in = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
setImageBitmap(result);
}
}
}
|
Activity
/** * 模拟新闻客户端 1. public class MainActivity extends Activity {
private ListView lv;
private List<NewsItems> list;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
NewsAsyncTask newsAsyncTask = new NewsAsyncTask(this);
try {
newsAsyncTask.execute(new URL(getResources().getString(R.string.path)));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
}
private class NewsAsyncTask extends AsyncTask<URL,
Integer, List<NewsItems>>{
private List<NewsItems> list = null ;
//对话框
private ProgressDialog pDialog;
//上下文
private Context mContext;
//构造函数
public NewsAsyncTask(Context mContext){
this.mContext = mContext;
}
@Override
protected List<NewsItems> doInBackground(URL...
params) {
try {
//获取连接
HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();
//设置连接连接方法
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
//获取响应码
int code = conn.getResponseCode();
if(code == 200){
//获取输入流
InputStream in = conn.getInputStream();
//解析XML
list=NewsClientService.getNewsInfo(in);
}
return list;
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(List<NewsItems>
result) {
lv.setAdapter(new MyBaseAdapter(result));
//设置对话框消失
pDialog.dismiss();
}
@Override
protected void onPreExecute() {
//初始化对象话进度条
pDialog = new ProgressDialog(MainActivity.this);
//设置标题
pDialog.setTitle("新闻加载中");
//设置内容
pDialog.setMessage("正在加载中........惊喜稍后呈现");
//设置是否可以取消 true可以取消
pDialog.setIndeterminate(true);
//设置风格
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//设置最大进度
pDialog.setMax(100);
//显示
pDialog.show();
}
@Override
protected void onProgressUpdate(Integer... values)
{
//设置时度
pDialog.setProgress(values[0]);
}
}
* ListView 适配器
private class MyBaseAdapter extends BaseAdapter
{
private static final String TAG = "MyBaseAdapter";
private List<NewsItems> list ;
public MyBaseAdapter(List<NewsItems> list){
this.list=list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
NewsItems newsItems = list.get(position);
Log.i(TAG, newsItems.getTitle());
View view;
if(convertView==null){
view = View.inflate(MainActivity.this, R.layout.news_items,
null);
}else{
view = convertView;
}
//图片
com.itheima.newsclient.smartview.MySmartView iv_icon
=(com.itheima.newsclient.smartview.MySmartView)
view.findViewById(R.id.iv_icon);
iv_icon.setImage(newsItems.getImageUrl());
//标题
TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_title.setText(newsItems.getTitle());
//描述
TextView tv_desc = (TextView) view.findViewById(R.id.tv_desc);
tv_desc.setText(newsItems.getDescription());
//评论
TextView tv_comm = (TextView) view.findViewById(R.id.tv_comm);
String type = newsItems.getType();
if(type.equals("1")){
tv_comm.setBackgroundColor(Color.RED);
tv_comm.setText("军报"+newsItems.getComment());
}else if(type.equals("2")){
tv_comm.setBackgroundColor(Color.BLUE);
tv_comm.setText("实时"+newsItems.getComment());
}else if(type.equals("3")){
tv_comm.setBackgroundColor(Color.GREEN);
tv_comm.setText("娱乐"+newsItems.getComment());
}else if(type.equals("4")){
tv_comm.setBackgroundColor(Color.GRAY);
tv_comm.setText("生活"+newsItems.getComment());
}
return view;
}
}
}
|
7.源生GET与POST请求
本地TOMCAT运行服务端写了一个Servlet
/** * LoginServlet * @Decription 处理登录请求的Servlet @WebServlet(urlPatterns={"/login"}) public class LoginServlet extends HttpServlet {
@SuppressWarnings("deprecation")
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
/*
* 获取用户名与密码并转换为UTF-8
*/
String user = request.getParameter("username");
/*String encode = URLEncoder.encode(user,"iso8859-1");
String decode = URLDecoder.decode(encode, "UTF-8");*/
System.out.println("================get===============");
String username =new String(user.getBytes("iso8859-1"),"utf-8");
System.out.println("get用户名:"+username);
String pwd=request.getParameter("password");
String password = new String(pwd.getBytes("iso8859-1"),
"UTF-8");
System.out.println("get密码:"+password);
/*
* 这里写死用户名与密码,
* 正常是去数据库查询
*/
PrintWriter writer = response.getWriter();
if("admin".equals(username)&&
"admin".equals(password)){
writer.write("SUCCESS");
}else{
writer.write("FAILURE");
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
System.out.println("================post===============");
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("post username:"+username+",password:
"+password);
if("admin".equals(username) &&
"admin".equals(password)){
response.getWriter().print("SUCCESS");
}else{
response.getWriter().print("failure");
}
}
} |
工具类
public class StreamUtils {
public static String decode(InputStream in)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len=0;
byte [] buf = new byte[1024];
while((len=in.read(buf))!=-1){
baos.write(buf, 0, len);
}
in.close();
baos.close();
return baos.toString();
}
} |
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/qq"/>
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入登录用户名"/>
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="请输入密码"/>
<Button
android:onClick="login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"/>
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout> |
Activity
public class MainActivity extends Activity { protected static final int ERROR = 0; protected static final int SUCCESS = 1; * 用户名 private EditText et_name; * 密码 private EditText et_pwd; * 结果 private TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_name);
et_pwd = (EditText) findViewById(R.id.et_pwd);
tv_result = (TextView) findViewById(R.id.tv_result);
}
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
tv_result.setText(msg.obj.toString());
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络异常",
Toast.LENGTH_SHORT).show();
break;
}
};
};
* 登录点击事件
* @param v
* 按键
public void login(View v) {
final String username = et_name.getText().toString().trim();
final String password = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password))
{
Toast.makeText(this, "用户名或者密码不能为空",
Toast.LENGTH_SHORT).show();
return;
}
new Thread() {
public void run() {
String path = getResources().getString(R.string.path);
try {
path = path + "?username="
+ URLEncoder.encode(username, "UTF-8")
+ "&password="
+ URLEncoder.encode(password, "UTF-8");
//建立连接
URL url = new URL(path);
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式与连接超时时间
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
//获取响应码
int code = conn.getResponseCode();
//判断响应异常
if(code==200){
//获取输入
InputStream in = conn.getInputStream();
//解析
String result=StreamUtils.decode(in);
//设置消息
Message msg= Message.obtain();
msg.what=SUCCESS;
msg.obj=result;
//发送消息
handler.sendMessage(msg);
}else{
sendErrorMessage();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
sendErrorMessage();
} catch (IOException e) {
e.printStackTrace();
sendErrorMessage();
}
}
private void sendErrorMessage() {
//设置消息
Message msg= Message.obtain();
msg.what=ERROR;
//发送消息
handler.sendMessage(msg);
};
}.start();
}
} |
Post
public class MainActivity extends Activity { protected static final int ERROR = 0; protected static final int SUCCESS = 1; * 用户名 private EditText et_name; * 密码 private EditText et_pwd;
* 结果
*/
private TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_name);
et_pwd = (EditText) findViewById(R.id.et_pwd);
tv_result = (TextView) findViewById(R.id.tv_result);
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
tv_result.setText(msg.obj.toString());
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络异常",
Toast.LENGTH_SHORT)
.show();
break;
}
};
};
* 登录点击事件
* @param v
* 按键
public void login(View v) {
final String username = et_name.getText().toString().trim();
final String password = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password))
{
Toast.makeText(this, "用户名或者密码不能为空",
Toast.LENGTH_SHORT).show();
return;
}
new Thread() {
public void run() {
String path = getResources().getString(R.string.path);
try {
String params = "username="
+ URLEncoder.encode(username, "UTF-8")
+ "&password="
+ URLEncoder.encode(password, "UTF-8");
* String params = "username=" + username
+ "&password=" +
* password;
// 建立连接
URL url = new URL(path);
// 打开连接
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 设置请求方式与连接超时时间
conn.setRequestMethod("POST");
conn.setConnectTimeout(5000);
// 设置请求头
// Content-Type: application/x-www-form-urlencoded
// Content-Length: 25
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",
params.length()
+ "");
// 设置输出
conn.setDoOutput(true);
// 把参数输出到服务器
OutputStream out = conn.getOutputStream();
out.write(params.getBytes());
// 获取响应码
int code = conn.getResponseCode();
// 判断响应异常
if (code == 200) {
// 获取输入
InputStream in = conn.getInputStream();
// 解析
String result = StreamUtils.decode(in);
// 设置消息
Message msg = Message.obtain();
msg.what = SUCCESS;
msg.obj = result;
// 发送消息
handler.sendMessage(msg);
} else {
sendErrorMessage();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
sendErrorMessage();
} catch (IOException e) {
e.printStackTrace();
sendErrorMessage();
}
}
private void sendErrorMessage() {
// 设置消息
Message msg = Message.obtain();
msg.what = ERROR;
// 发送消息
handler.sendMessage(msg);
};
}.start();
}
} |
8.使用Apache的HttpClient完成
8.1get
public class MainActivity extends Activity { protected static final int ERROR = 0; protected static final int SUCCESS = 1;
* 用户名 private EditText et_name; * 密码 private EditText et_pwd;
* 结果 private TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_name);
et_pwd = (EditText) findViewById(R.id.et_pwd);
tv_result = (TextView) findViewById(R.id.tv_result);
}
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
tv_result.setText(msg.obj.toString());
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络异常",
Toast.LENGTH_SHORT).show();
break;
}
};
};
* 登录点击事件
* @param v
* 按键
public void login(View v) {
final String username = et_name.getText().toString().trim();
final String password = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password))
{
Toast.makeText(this, "用户名或者密码不能为空",
Toast.LENGTH_SHORT).show();
return;
}
new Thread() {
public void run() {
String path = getResources().getString(R.string.path);
try {
path = path + "?username="
+ URLEncoder.encode(username, "UTF-8")
+ "&password="
+ URLEncoder.encode(password, "UTF-8");
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(path);
//建立获取响应
HttpResponse response = client.execute(httpGet);
//获取响应码
int code = response.getStatusLine().getStatusCode();
//判断响应异常
if(code==200){
//获取输入
InputStream in = response.getEntity().getContent();
//解析
String result=StreamUtils.decode(in);
//设置消息
Message msg= Message.obtain();
msg.what=SUCCESS;
msg.obj=result;
//发送消息
handler.sendMessage(msg);
}else{
sendErrorMessage();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
sendErrorMessage();
} catch (IOException e) {
e.printStackTrace();
sendErrorMessage();
}
}
private void sendErrorMessage() {
//设置消息
Message msg= Message.obtain();
msg.what=ERROR;
//发送消息
handler.sendMessage(msg);
};
}.start();
}
} |
8.2 post
public class MainActivity extends Activity { protected static final int ERROR = 0; protected static final int SUCCESS = 1; * 用户名 private EditText et_name; * 密码 private EditText et_pwd; * 结果 private TextView tv_result;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.et_name);
et_pwd = (EditText) findViewById(R.id.et_pwd);
tv_result = (TextView) findViewById(R.id.tv_result);
}
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
tv_result.setText(msg.obj.toString());
break;
case ERROR:
Toast.makeText(MainActivity.this, "网络异常",
Toast.LENGTH_SHORT).show();
break;
}
};
};
/**
* 登录点击事件
*
* @param v
* 按键
*/
public void login(View v) {
final String username = et_name.getText().toString().trim();
final String password = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password))
{
Toast.makeText(this, "用户名或者密码不能为空",
Toast.LENGTH_SHORT).show();
return;
}
new Thread() {
public void run() {
String path = getResources().getString(R.string.path);
try {
/* String params = "username="
+ URLEncoder.encode(username, "UTF-8")
+ "&password="
+ URLEncoder.encode(password, "UTF-8");*/
HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("username",username));
list.add(new BasicNameValuePair("password",password));
httpPost.setEntity(new UrlEncodedFormEntity(list,
"UTF-8"));
//建立获取响应
HttpResponse response = client.execute(httpPost);
//获取响应码
int code = response.getStatusLine().getStatusCode();
//判断响应异常
if(code==200){
//获取输入
InputStream in = response.getEntity().getContent();
//解析
String result=StreamUtils.decode(in);
//设置消息
Message msg= Message.obtain();
msg.what=SUCCESS;
msg.obj=result;
//发送消息
handler.sendMessage(msg);
}else{
sendErrorMessage();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
sendErrorMessage();
} catch (IOException e) {
e.printStackTrace();
sendErrorMessage();
}
}
private void sendErrorMessage() {
//设置消息
Message msg= Message.obtain();
msg.what=ERROR;
//发送消息
handler.sendMessage(msg);
};
}.start();
}
} |
9.使用开源的框架完成
https://github.com/loopj/android-async-http
9.1 get
/** * 登录点击事件 * * @param v * 按键 */ public void login(View v) {
final String username = et_name.getText().toString().trim();
final String password = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password))
{
Toast.makeText(this, "用户名或者密码不能为空",
Toast.LENGTH_SHORT).show();
return;
}
String path = getResources().getString(R.string.path);
/* try {
path = path + "?username="
+ URLEncoder.encode(username, "UTF-8")
+ "&password="
+ URLEncoder.encode(password, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}*/
//使用开源框架 https://github.com/loopj/android-async-http
AsyncHttpClient httpClient = new AsyncHttpClient();
/* httpClient.get(path, new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(int statusCode, Header[]
headers, byte[] responseBody) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
@Override
public void onFailure(int statusCode, Header[]
headers,
byte[] responseBody, Throwable error) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
});*/
RequestParams params = new RequestParams();
params.put("username", username);
params.put("password", password);
httpClient.get(path, params, new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(int statusCode, Header[]
headers, byte[] responseBody) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
@Override
public void onFailure(int statusCode, Header[]
headers,
byte[] responseBody, Throwable error) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
});
} |
9.2post
/** * 登录点击事件 * * @param v * 按键 */ public void login(View v) {
final String username = et_name.getText().toString().trim();
final String password = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password))
{
Toast.makeText(this, "用户名或者密码不能为空",
Toast.LENGTH_SHORT).show();
return;
}
String path = getResources().getString(R.string.path);
/* try {
path = path + "?username="
+ URLEncoder.encode(username, "UTF-8")
+ "&password="
+ URLEncoder.encode(password, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}*/
AsyncHttpClient httpClient = new AsyncHttpClient();
/* httpClient.get(path, new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(int statusCode, Header[]
headers, byte[] responseBody) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
@Override
public void onFailure(int statusCode, Header[]
headers,
byte[] responseBody, Throwable error) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
});*/
RequestParams params = new RequestParams();
params.put("username", username);
params.put("password", password);
httpClient.post(path, params, new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(int statusCode, Header[]
headers, byte[] responseBody) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
@Override
public void onFailure(int statusCode, Header[]
headers,
byte[] responseBody, Throwable error) {
tv_result.setText("code"+statusCode+"响应体"+new
String(responseBody));
}
});
} |
10.使用开源框架上传文件
服务器,使用Servlet完成使用Apache的commons-fileupload,commons-io写的文件上传
public class UploadServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
try {
//ArrayList<String> list=initList();
// 获取磁盘文件工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置初始值
setFactory(factory);
/*
* // 配置初始化值缓冲区 factory.setSizeThreshold(1024 *
1024); // 设置缓冲 区文件
* String bufPath = getServletContext().getRealPath("/temp");
*
* factory.setRepository(new File(bufPath));
*/
// 获取上传对象解析器
ServletFileUpload upload = new ServletFileUpload(factory);
// 判断 是不是多部分组成
if (!upload.isMultipartContent(request)) {
request.setAttribute("msg", "表单不是多部分组成,查看enctype");
request.getRequestDispatcher("/upload.jsp").forward(request,
response);
return;
}
// 初始化
setFileUpload(upload);
// 设置 字符编码
/*
* upload.setHeaderEncoding("utf-8");
// 设置单个文件大小
* upload.setFileSizeMax(1024 * 1024 * 5); // 设置总文件大小
* upload.setSizeMax(1024 * 1024 * 20);
*
* // 设置上传监听器 upload.setProgressListener(new ProgressListener()
{
*
* public void update(long pBytesRead, long pContentLength,
int
* pItems) { System.out.println("已经读:"
+ pBytesRead + "总共大小 :" +
* pContentLength + "第" + pItems + "个");
*
* } });
*/
// 获取请求的列表
List<FileItem> parseRequest = upload.parseRequest(request);
// 遍历
for (FileItem item : parseRequest) {
// 判断 是不是普通表单数据
if (item.isFormField()) {
String fieldname = item.getFieldName();
String fieldValue = item.getString("UTF-8");
System.out.println("表单:" + fieldname
+ "," + fieldValue);
} else {
// 上传路径
String uploadPath = getServletContext().getRealPath(
"/WEB-INF/upload");
// 获取文件名
String filename = item.getName();
int index=filename.lastIndexOf(".");
String extname=filename.substring(index);
//判断上传的文件是否在上传列表 中
/*if(!list.contains(extname)){
request.setAttribute("msg", "文件类型"+extname+"不在上传的类型中");
request.getRequestDispatcher("/upload.jsp").forward(request,
response);
return;
}*/
// 获取输入流
InputStream in = item.getInputStream();
filename = UUID.randomUUID().toString().replace("-",
"")
+ "_" + filename;
System.out.println(filename);
String savePath = genera(uploadPath, filename);
System.out.println(savePath);
//上传文件
uploadFile(in,savePath,filename);
//删除缓存
item.delete();
}
//上传失败的缓冲也清除
item.delete();
}
} catch (FileUploadBase.FileSizeLimitExceededException
e) {
request.setAttribute("msg", "单个文件大小超过限制");
request.getRequestDispatcher("/upload.jsp").forward(request,
response);
return;
} catch (FileUploadBase.SizeLimitExceededException
e) {
request.setAttribute("msg", "文件总大小超过限制");
request.getRequestDispatcher("/upload.jsp").forward(request,response);
return;
} catch (MyException e) {
request.setAttribute("msg", "文件类型不正确");
request.getRequestDispatcher("/upload.jsp").forward(request,
response);
return;
}catch (Exception e) {
e.printStackTrace();
request.setAttribute("msg", "出错了");
request.getRequestDispatcher("/upload.jsp").forward(request,
response);
return;
}
request.setAttribute("msg", "上传成功");
request.getRequestDispatcher("/upload.jsp").forward(request,
response);
}
* 初始化可以上传的文件列表
* @return
private ArrayList<String> initList() {
ArrayList<String> list=new ArrayList<String>();
list.add(".jpg");
list.add(".rar");
list.add(".txt");
list.add(".png");
return list;
}
/**
* 上传文件
* @param in 输入流
* @param savePath 保存路径
* @param filename 文件名称
* @throws Exception
*/
private void uploadFile(InputStream in, String
savePath, String filename) throws Exception {
File file = new File(savePath, filename);
// 设置输出流
OutputStream out = new FileOutputStream(file);
int len = 0;
byte[] buf = new byte[1024];
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
/**
* 使用哈希值,做散列的文件目录
*
* @param uploadPath
* @param filename
* @return
*/
private String genera(String uploadPath, String
filename) {
System.out.println(uploadPath);
int hashCode = filename.hashCode();
StringBuilder sb = new StringBuilder();
while (hashCode > 0) {
int tmp = hashCode & 0xf;
sb.append("/");
sb.append(tmp + "");
hashCode = hashCode >> 4;
}
System.out.println(sb.toString());
String path = uploadPath + sb.toString();
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return path;
}
/**
* 对象解析器进行初始化
*
* @param upload
*/
private void setFileUpload(ServletFileUpload upload)
{
// 设置 字符编码
upload.setHeaderEncoding("utf-8");
// 设置单个文件大小
upload.setFileSizeMax(1024 * 1024 * 20);
// 设置总文件大小
upload.setSizeMax(1024 * 1024 * 100);
// 设置上传监听器
upload.setProgressListener(new ProgressListener()
{
public void update(long pBytesRead, long pContentLength,
int pItems) {
System.out.println("已经读:" + pBytesRead
+ "总共大小 :"
+ pContentLength + "第" + pItems + "个");
}
});
}
/**
* 为工厂设置初始值
*/
private void setFactory(DiskFileItemFactory factory)
{
// 配置初始化值缓冲区
factory.setSizeThreshold(1024 * 1024);
// 设置缓冲 区文件
String bufPath = getServletContext().getRealPath("/temp");
factory.setRepository(new File(bufPath));
}
} |
客户端
权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<!-- 这里把文件写死了 -->
<EditText
android:id="@+id/et_file"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入要上传的文件路径"
android:text="/mnt/sdcard/gm.mp3" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="upload"
android:text="上传" />
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tv_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
/>
</LinearLayout> |
Activity
public class MainActivity extends Activity {
protected static final String TAG = "MainActivity";
/*
* 输入的文件地址
*/
private EditText et_file;
/*
* 进度条
*/
private ProgressBar pb;
/*
* 显示时度值
*/
private TextView tv_display;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_file = (EditText) findViewById(R.id.et_file);
pb = (ProgressBar) findViewById(R.id.pb);
tv_display = (TextView) findViewById(R.id.tv_display);
}
/**
* 上传文件
*
* @param v
* 上传按键
*/
public void upload(View v) {
//获取输入的文件地址
String str = et_file.getText().toString().trim();
File file = new File(str);
// 使用开源框架 地址https://github.com/wyouflf/xUtils
HttpUtils httpUtils = new HttpUtils();
RequestParams params = new RequestParams();
params.addBodyParameter("file", file);
// 获取上传路径,写在values--strings中
String url = "http://192.168.1.104:8080/MyDay11upload/upload";
Log.i(TAG, url);
// 发送文件
httpUtils.send(HttpMethod.POST, url, params,
new RequestCallBack<String>() {
@Override
public void onFailure(HttpException error, String
msg) {
Toast.makeText(MainActivity.this, "上传失败:====="
+ msg,
Toast.LENGTH_SHORT).show();
}
@Override
public void onSuccess(ResponseInfo<String>
responseInfo) {
Toast.makeText(MainActivity.this, "上传成功:=====",
Toast.LENGTH_SHORT).show();
Header[] headers = responseInfo.getAllHeaders();
for (Header header : headers) {
Log.i(TAG, "key:---->" + header.getName()
+ "values---->" + header.getValue());
}
}
@Override
public void onLoading(long total, long current,
boolean isUploading) {
pb.setMax((int) total);
pb.setProgress((int) current);
tv_display.setText("当前进度:"+current+"
总进度:"+total);
}
});
}
} |
11.AsyncTask
* 使用异步下载 * 1.创建AsyncTaskr子类,并为三个泛型参数指定类型,如果某个泛型参数不需要指定类型则可以指定为Void * 2.根据需要实现AsyncTAsk的方法 * doInBackground 重写这个方法,后台线程将要完成的任务,
该方法可以调用publishProgress(Progresss....values)方法更新任务的进度 * onProExecute():该方法将在后台耗时操作前被调用,通常该方法,
用于完成一些初始化准备工作,比如在界面显示初始化进度等 * onPostExcute(Result result) 当doInBackground完成以后,系统会自动调用onPostExecute()方法,
并将doInBackground方法的返回值传给该方法 * * 3.调用AsyncTask子类的实例execute(Params..params)开始执行耗时任务 * 注意: * 必须在UI线程中创建AsyncTasck的实例 * 必须在UI线程中调用AsyncTask的execute()方法 * doInBackground,onProExecute,onPostExcute,opProgressUpdate()方法,
不应该用程序员代码调用,而是用Android系统负责调用 * 每个AsyncTask只能执行一次,多次调用将会引发异常 |
/** * 使用异步下载 * 1.创建AsyncTaskr子类,并为三个泛型参数指定类型,如果某个泛型参数不需要指定类型则可以指定为Void * 2.根据需要实现AsyncTAsk的方法 * doInBackground 重写这个方法,后台线程将要完成的任务,
该方法可以调用publishProgress(Progresss....values)方法更新任务的进度 * onProExecute():该方法将在后台耗时操作前被调用,通常该方法,
用于完成一些初始化准备工作,比如在界面显示初始化进度等 * onPostExcute(Result result) 当doInBackground完成以后,
系统会自动调用onPostExecute()方法,并将doInBackground方法的返回值传给该方法 * 3.调用AsyncTask子类的实例execute(Params..params)开始执行耗时任务 * 注意: * 必须在UI线程中创建AsyncTasck的实例 * 必须在UI线程中调用AsyncTask的execute()方法 * doInBackground,onProExecute,onPostExcute,opProgressUpdate()方法,
不应该用程序员代码调用,而是用Android系统负责调用 * 每个AsyncTask只能执行一次,多次调用将会引发异常 public class MainActivity extends AppCompatActivity {
用户输入的url
private EditText tv_path;
*显示结果
private TextView tv_show;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_path = (EditText) findViewById(R.id.tv_path);
tv_show = (TextView) findViewById(R.id.tv_show);
}
* 响应按键点击下载事件
* @param v 当前按键
public void download(View v){
String path = tv_path.getText().toString().trim();
if(TextUtils.isEmpty(path)){
Toast.makeText(this,"下载路径不能为空",Toast.LENGTH_SHORT).show();
return;
}
DownloadTask task = new DownloadTask(this);
try {
//开始执行
task.execute(new URL(path));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
* 可变参数
* 第一个:param 表示传入的参数
* 第二个:progress后台任务成的进度值的类型
* 第三个:Result,返回的类型
private class DownloadTask extends AsyncTask<URL,Integer,String>{
上下文
private Context mContext;
进度条
private ProgressDialog progressDialog;
定义记录读取的行数
private int hasRead = 0;
public DownloadTask(Context context) {
this.mContext = context;
}
@Override
protected String doInBackground(URL... params)
{
StringBuilder sb = new StringBuilder();
try {
//打开连接
URLConnection conn = params[0].openConnection();
//开始读读
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
String line=null;
//开始读
while((line=br.readLine())!=null){
sb.append(line+"\n");
}
//返回将因被OnPostexecute方法调用接收返回值
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
* 初始化操作
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(mContext);
//设置对话框标题
progressDialog.setTitle("任务正在执行中");
//设置对话显示的内容
progressDialog.setMessage("任务在拼命加载中...请稍后......");
//设置对话框不能用 取消 按键关闭
progressDialog.setCancelable(false);
//设置该进度条最在时度值
progressDialog.setMax(100);
//设置时度条的风格
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//设置是否显示时度条 不确定的是否显示true为不显示,
progressDialog.setIndeterminate(false);
progressDialog.show();
}
@Override
protected void onProgressUpdate(Integer... values)
{
tv_show.setText("已经读取====" + values[0]
+ "=====行");
progressDialog.setProgress(values[0]);
}
* 调用 doInBackground,并接收其返回值
* @param s
@Override
protected void onPostExecute(String s) {
//设置显示
tv_show.setText(s);
//进度对话框消失不可见
progressDialog.dismiss();
}
}
}
|
12.多线程断点下载
JAVA实现
package com.it.download;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
* 多线程断点下载,续传
* @Decription TODO
public class DownTask {
// 下载地址
public static String path = "http://192.168.1.104:8080/itest/gm.mp3";
/*
* 线程数
*/
public static int threadCount = 5;
/*
* 当前运行的线程数
*/
public static int runninThreadCount =threadCount;
public static void main(String[] args) {
// 开始连接网络
try {
URL url = new URL(path);
// 打开网络连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方式与连接超时时间
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// 获取获取码
int code = conn.getResponseCode();
if (code == 200) {
int length = conn.getContentLength();
System.out.println("长度:" + length);
// 在本地创建一个与服务一样大小的文件
String fileName = getFileName(path);
RandomAccessFile raf = new RandomAccessFile(fileName,
"rw");
// 设置文件的大小
raf.setLength(length);
raf.close();
// 计算每个线程下载的大小
int blockSize = length % threadCount == 0 ? length
/ threadCount : length / threadCount + 1;
//
for (int threadId = 0; threadId < threadCount;
threadId++) {
// 计算开始下载的位置与结束下载的文置
int startIndex = threadId * blockSize;
int endIndex = startIndex + blockSize;
if (endIndex >= length) {
endIndex = length;
}
new DownThread(threadId, startIndex, endIndex).start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文件名称
*
* @param path
* 路径
* @return 返回文件名称
*/
public static String getFileName(String path)
{
int index = path.lastIndexOf("/");
return path.substring(index + 1);
}
/**
* 下载的线程
*
* @Decription TODO
private static class DownThread extends Thread
{
// 线程IP
private int threadId;
// 开始位置
private int startIndex;
// 结束位置
private int endIndex;
private int currentPosition;
public DownThread(int threadId, int startIndex,
int endIndex) {
super();
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.currentPosition = startIndex;
}
@Override
public void run() {
System.out.println("线程:" + threadId
+ ",==开始下载位置:" + startIndex
+ "=========>结束位置:" + endIndex);
// 开始连接网络
try {
URL url = new URL(path);
// 打开连接
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 设置请求方式与连接超时时间
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// 设置请求头,多线程下载,只获取一部分数据
String fileName = getFileName(path);
RandomAccessFile rf = new RandomAccessFile(fileName,
"rw");
// 首先确认有没有下载过拿到文件
File fFile = new File(threadId + ".position");
// 判断文件是不是存在,存在就说明下载过
if (fFile.exists()) {
//读取出下载的进度
BufferedReader br = new BufferedReader(new FileReader(fFile));
String readLine = br.readLine();
currentPosition = Integer.parseInt(readLine);
conn.setRequestProperty("range", "bytes="
+ currentPosition
+ "-" + endIndex);
rf.seek(currentPosition);
br.close();
} else {
// 说明没有下载过
conn.setRequestProperty("range", "bytes="
+ startIndex
+ "-" + endIndex);
rf.seek(currentPosition);
}
// 获取获取码部分数据为206
int code = conn.getResponseCode();
if (code == 206) {
InputStream in = conn.getInputStream();
// 设置开始位置
// 开始写放
int len = 0;
byte[] buf = new byte[1024];
while ((len = in.read(buf)) != -1) {
rf.write(buf, 0, len);
// 用来记录当前的下载位置
currentPosition += len;
RandomAccessFile positionFile = new RandomAccessFile(
threadId + ".position", "rwd");
// 写入文件 建立缓存
positionFile.write((currentPosition + "").getBytes());
positionFile.close();
}
rf.close();
in.close();
System.out.println("线程:" + threadId
+ "下载完成了");
//把下载完成的文件标记为完成
File file = new File(threadId+".position");
file.renameTo(new File(threadId+".position.finished"));
synchronized (DownTask.class) {
//线程数-1
runninThreadCount--;
if(runninThreadCount<=0){
for(int i=0;i<threadCount;i++){
File delFile = new File(i+".position.finished");
//删除
delFile.delete();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
} |
|