您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
安卓第八天笔记--网络编程二
 
作者:森林森 来自于:博客园 发布于 2016-3-23
  2889  次浏览      22
 

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();
}
}

}
}

   
2889 次浏览       22
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   

Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合

领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...