在Android开发中我们经常有这样的需求,从服务器上下载xml或者JSON类型的数据,其中包括一些图片资源,本demo模拟了这个需求,从网络上加载XML资源,其中包括图片,我们要做的解析XML里面的数据,并且把图片缓存到本地一个cache目录里面,并且用一个自定义的Adapter去填充到LIstView,demo运行效果见下图:
通过这个demo,要学会有一下几点
1.怎么解析一个XML
2.demo中用到的缓存图片到本地一个临时目录的思想是怎样的?
3.AsyncTask类的使用,因为要去异步的加载数据,就必须开启线程,但是在开启线程的时有时候不能很好的控制线程的数量,线程数量太大的时候手机会很快被卡死 这里就采用AsynsTask类的去解决这个问题,这个类里面封装了线程池的技术,从而保证不会因开启过多的线程而消耗太多的资源
4.本demo中的Handler类的使用情况 5.自定义adapter的使用
下面是demo中的Activity。
01 |
public
class MainActivity extends
Activity { |
02 |
protected
static final
int SUCCESS_GET_CONTACT = 0 ; |
03 |
private
ListView mListView; |
04 |
private
MyContactAdapter mAdapter; |
07 |
private
Handler mHandler = new
Handler(){ |
08 |
public
void handleMessage(android.os.Message msg) { |
09 |
if (msg.what == SUCCESS_GET_CONTACT){ |
10 |
List<Contact> contacts = (List<Contact>) msg.obj; |
11 |
mAdapter =
new MyContactAdapter(getApplicationContext(),contacts,cache); |
12 |
mListView.setAdapter(mAdapter); |
18 |
public
void onCreate(Bundle savedInstanceState) { |
19 |
super .onCreate(savedInstanceState); |
20 |
setContentView(R.layout.main); |
22 |
mListView = (ListView) findViewById(R.id.listview); |
25 |
cache =
new File(Environment.getExternalStorageDirectory(),
"cache" ); |
34 |
ContactService service =
new ContactService(); |
35 |
List<Contact> contacts =
null ; |
37 |
contacts = service.getContactAll(); |
38 |
}
catch (Exception e) { |
43 |
Message msg =
new Message(); |
44 |
msg.what = SUCCESS_GET_CONTACT; |
46 |
mHandler.sendMessage(msg); |
52 |
protected
void onDestroy() { |
55 |
File[] files = cache.listFiles(); |
56 |
for (File file :files){ |
Activity中,注意以下几点,
1.初始化了一个缓存目录,这个目录最好是应用开启就去创建好,为手续缓存图片做准备,在这里把数据存放在SDCard上
2.要去服务器加载数据,这个耗时操作最好是去开启线程加载数据,加载完毕后去异步的更新UI线程,利用Handler机制能很好的解决这个问题,
3.最后退出应用的时候,要删掉缓存目录和目录里面的数据,避免给手机制造很多的垃圾文件
下面就是一个Service类了,
01 |
public
class ContactService { |
06 |
public
List<Contact> getContactAll() throws
Exception { |
07 |
List<Contact> contacts =
null ; |
08 |
String Parth =
"http://192.168.1.103:8080/myweb/list.xml" ; |
09 |
URL url =
new URL(Parth); |
10 |
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
11 |
conn.setConnectTimeout( 3000 ); |
12 |
conn.setRequestMethod( "GET" ); |
13 |
if
(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { |
14 |
InputStream is = conn.getInputStream(); |
16 |
contacts = xmlParser(is); |
24 |
private
List<Contact> xmlParser(InputStream is) throws
Exception { |
25 |
List<Contact> contacts =
null ; |
26 |
Contact contact =
null ; |
27 |
XmlPullParser parser = Xml.newPullParser(); |
28 |
parser.setInput(is,
"UTF-8" ); |
29 |
int
eventType = parser.getEventType(); |
30 |
while
((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) { |
32 |
case
XmlPullParser.START_TAG: |
33 |
if
(parser.getName().equals( "contacts" )) { |
34 |
contacts =
new ArrayList<Contact>(); |
35 |
}
else if
(parser.getName().equals( "contact" )) { |
36 |
contact =
new Contact(); |
37 |
contact.setId(Integer.valueOf(parser.getAttributeValue( 0 ))); |
38 |
}
else if
(parser.getName().equals( "name" )) { |
39 |
contact.setName(parser.nextText()); |
40 |
}
else if
(parser.getName().equals( "image" )) { |
41 |
contact.setImage(parser.getAttributeValue( 0 )); |
45 |
case
XmlPullParser.END_TAG: |
46 |
if
(parser.getName().equals( "contact" )) { |
47 |
contacts.add(contact); |
59 |
public
Uri getImageURI(String path, File cache) throws
Exception { |
60 |
String name = MD5.getMD5(path) + path.substring(path.lastIndexOf( "." )); |
61 |
File file =
new File(cache, name); |
64 |
return
Uri.fromFile(file); |
67 |
URL url =
new URL(path); |
68 |
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
69 |
conn.setConnectTimeout( 5000 ); |
70 |
conn.setRequestMethod( "GET" ); |
71 |
conn.setDoInput( true ); |
72 |
if
(conn.getResponseCode() == 200 ) { |
74 |
InputStream is = conn.getInputStream(); |
75 |
FileOutputStream fos =
new FileOutputStream(file); |
76 |
byte [] buffer =
new byte [ 1024 ]; |
78 |
while
((len = is.read(buffer)) != - 1 ) { |
79 |
fos.write(buffer,
0 , len); |
84 |
return
Uri.fromFile(file); |
Serivce类中,注意以下几点
1.HttpURLConnection conn = (HttpURLConnection) url.openConnection();获取一个链接,从而进行通讯
2.怎么利用XxmlPullPaser类去解析XML,从而把数据封装成对象
3.getImageURI(String path, File cache) 这个方法具体实现
4.Uri.fromFile(file);这个方法能够直接返回一个Uri来
下面是自定义的Adapter类,
001 |
public
class MyContactAdapter extends
BaseAdapter { |
003 |
protected
static final
int SUCCESS_GET_IMAGE = 0 ; |
004 |
private
Context context; |
005 |
private
List<Contact> contacts; |
007 |
private
LayoutInflater mInflater; |
010 |
public
MyContactAdapter(Context context, List<Contact> contacts, File cache) { |
011 |
this .context = context; |
012 |
this .contacts = contacts; |
015 |
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
019 |
public
int getCount() { |
020 |
return
contacts.size(); |
024 |
public
Object getItem( int
position) { |
025 |
return
contacts.get(position); |
029 |
public
long getItemId( int
position) { |
034 |
public
View getView( int
position, View convertView, ViewGroup parent) { |
039 |
if
(convertView != null ) { |
042 |
view = mInflater.inflate(R.layout.item,
null ); |
045 |
ImageView iv_header = (ImageView) view.findViewById(R.id.iv_header); |
046 |
TextView tv_name = (TextView) view.findViewById(R.id.tv_name); |
048 |
Contact contact = contacts.get(position); |
051 |
asyncloadImage(iv_header, contact.image); |
052 |
tv_name.setText(contact.name); |
057 |
private
void asyncloadImage(ImageView iv_header, String path) { |
058 |
ContactService service =
new ContactService(); |
059 |
AsyncImageTask task =
new AsyncImageTask(service, iv_header); |
063 |
private
final class
AsyncImageTask
extends
AsyncTask<String, Integer, Uri> {
|
065 |
private
ContactService service; |
066 |
private
ImageView iv_header; |
068 |
public
AsyncImageTask(ContactService service, ImageView iv_header) { |
069 |
this .service = service; |
070 |
this .iv_header = iv_header; |