Android 비동기 로 그림 을 다운로드 하고 로 컬 DEMO 에 그림 을 캐 시 합 니 다.
이 demo 를 통 해 몇 가 지 를 배 워 야 합 니까?
1.XML 을 어떻게 해석 합 니까?
2.demo 에서 사용 하 는 캐 시 그림 을 로 컬 임시 디 렉 터 리 로 가 져 가 는 사상 은 어 떻 습 니까?
3.AsyncTask 류 의 사용 은 비동기 로 데 이 터 를 불 러 오 려 면 반드시 스 레 드 를 켜 야 하기 때 문 입 니 다.그러나 스 레 드 를 켤 때 스 레 드 의 수량 을 잘 제어 하지 못 할 때 도 있 습 니 다.스 레 드 수량 이 너무 많 을 때 핸드폰 이 곧 끊 겨 죽 습 니 다.여 기 는 Asyns Task 류 로 이 문 제 를 해결 합 니 다.이런 유형 에 스 레 드 탱크 를 밀봉 하 는 기술 이 있 습 니 다.따라서 너무 많은 스 레 드 를 켜 서 너무 많은 자원 을 소모 하지 않도록 보장 합 니 다.
4.이 demo 의 Handler 클래스 사용 현황 5.사용자 정의 adapter 사용
다음은 데모 의 액 티 비 티.
public class MainActivity extends Activity {
protected static final int SUCCESS_GET_CONTACT = 0;
private ListView mListView;
private MyContactAdapter mAdapter;
private File cache;
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what == SUCCESS_GET_CONTACT){
List<Contact> contacts = (List<Contact>) msg.obj;
mAdapter = new MyContactAdapter(getApplicationContext(),contacts,cache);
mListView.setAdapter(mAdapter);
}
};
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mListView = (ListView) findViewById(R.id.listview);
// , ,
cache = new File(Environment.getExternalStorageDirectory(), "cache");
if(!cache.exists()){
cache.mkdirs();
}
// , UI ,
new Thread(){
public void run() {
ContactService service = new ContactService();
List<Contact> contacts = null;
try {
contacts = service.getContactAll();
} catch (Exception e) {
e.printStackTrace();
}
// Message , ,
//Handler sendMessage() , UI
Message msg = new Message();
msg.what = SUCCESS_GET_CONTACT;
msg.obj = contacts;
mHandler.sendMessage(msg);
};
}.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
//
File[] files = cache.listFiles();
for(File file :files){
file.delete();
}
cache.delete();
}
}
Activity 에서 다음 과 같은 몇 가 지 를 주의 하 세 요.1.캐 시 디 렉 터 리 를 초기 화 했 습 니 다.이 디 렉 터 리 는 열 리 면 만 드 는 것 이 좋 습 니 다.수속 캐 시 그림 을 준비 하기 위해 SDCard 에 데 이 터 를 저장 하 는 것 이 좋 습 니 다.
2.서버 에 데 이 터 를 불 러 오 려 면 스 레 드 로 데 이 터 를 불 러 오 는 것 이 좋 습 니 다.불 러 온 후에 다른 단계 로 UI 스 레 드 를 업데이트 하고 Handler 체 제 를 이용 하여 이 문 제 를 잘 해결 할 수 있 습 니 다.
3.마지막 으로 앱 을 종료 할 때 캐 시 디 렉 터 리 와 디 렉 터 리 에 있 는 데 이 터 를 삭제 하고 핸드폰 에 쓰레기 파일 을 많이 만 들 지 않도록 해 야 합 니 다.
다음은 서비스 클래스 입 니 다.
public class ContactService {
/*
*
*/
public List<Contact> getContactAll() throws Exception {
List<Contact> contacts = null;
String Parth = "http://192.168.1.103:8080/myweb/list.xml";
URL url = new URL(Parth);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(3000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream is = conn.getInputStream();
// XmlPullParser
contacts = xmlParser(is);
return contacts;
} else {
return null;
}
}
// ,
private List<Contact> xmlParser(InputStream is) throws Exception {
List<Contact> contacts = null;
Contact contact = null;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, "UTF-8");
int eventType = parser.getEventType();
while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
if (parser.getName().equals("contacts")) {
contacts = new ArrayList<Contact>();
} else if (parser.getName().equals("contact")) {
contact = new Contact();
contact.setId(Integer.valueOf(parser.getAttributeValue(0)));
} else if (parser.getName().equals("name")) {
contact.setName(parser.nextText());
} else if (parser.getName().equals("image")) {
contact.setImage(parser.getAttributeValue(0));
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("contact")) {
contacts.add(contact);
}
break;
}
}
return contacts;
}
/*
* , ,
* path
*/
public Uri getImageURI(String path, File cache) throws Exception {
String name = MD5.getMD5(path) + path.substring(path.lastIndexOf("."));
File file = new File(cache, name);
// ,
if (file.exists()) {
return Uri.fromFile(file);//Uri.fromFile(path) URI
} else {
//
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
is.close();
fos.close();
// URI
return Uri.fromFile(file);
}
}
return null;
}
}
Serivce 클래스 중 다음 과 같은 몇 가 지 를 주의 하 십시오.1.HttpURLConnection conn = (HttpURLConnection) url.openConnection();링크 를 가 져 와 통신 합 니 다.
2.XxmlPullPaser 류 를 이용 하여 XML 을 분석 하여 데 이 터 를 대상 으로 봉인 하 는 방법
3.getImageURI(String path,File cache)라 는 방법 이 구체 적 으로 구현 되 었 습 니 다.
4.Uri.fromFile(file);이 방법 은 바로 Uri 로 돌아 올 수 있다.
다음은 사용자 정의 Adapter 클래스 입 니 다.
public class MyContactAdapter extends BaseAdapter {
protected static final int SUCCESS_GET_IMAGE = 0;
private Context context;
private List<Contact> contacts;
private File cache;
private LayoutInflater mInflater;
//
public MyContactAdapter(Context context, List<Contact> contacts, File cache) {
this.context = context;
this.contacts = contacts;
this.cache = cache;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return contacts.size();
}
@Override
public Object getItem(int position) {
return contacts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 1 item,
// 2
// 3 item
View view = null;
if (convertView != null) {
view = convertView;
} else {
view = mInflater.inflate(R.layout.item, null);
}
ImageView iv_header = (ImageView) view.findViewById(R.id.iv_header);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
Contact contact = contacts.get(position);
// ( + Handler ) ---> AsyncTask
asyncloadImage(iv_header, contact.image);
tv_name.setText(contact.name);
return view;
}
private void asyncloadImage(ImageView iv_header, String path) {
ContactService service = new ContactService();
AsyncImageTask task = new AsyncImageTask(service, iv_header);
task.execute(path);
}
private final class AsyncImageTask extends AsyncTask<String, Integer, Uri> {
private ContactService service;
private ImageView iv_header;
public AsyncImageTask(ContactService service, ImageView iv_header) {
this.service = service;
this.iv_header = iv_header;
}
//
@Override
protected Uri doInBackground(String... params) {
try {
return service.getImageURI(params[0], cache);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// ui
@Override
protected void onPostExecute(Uri result) {
super.onPostExecute(result);
//
if (iv_header != null && result != null) {
iv_header.setImageURI(result);
}
}
}
/**
*
*/
/*private void asyncloadImage(final ImageView iv_header, final String path) {
final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == SUCCESS_GET_IMAGE) {
Uri uri = (Uri) msg.obj;
if (iv_header != null && uri != null) {
iv_header.setImageURI(uri);
}
}
}
};
// , ,
Runnable runnable = new Runnable() {
@Override
public void run() {
ContactService service = new ContactService();
try {
// URI URI
Uri uri = service.getImageURI(path, cache);
Message msg = new Message();
msg.what = SUCCESS_GET_IMAGE;
msg.obj = uri;
mHandler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(runnable).start();
}*/
}
사용자 정의 Adapter 에 서 는 Async ImageTask 라 는 클래스 가 AsyncTask 클래스 를 계승 하 였 음 을 주의해 야 합 니 다.AsyncTask 는 Android 에서 비동기 작업 을 자주 하 는 클래스 로 스 레 드 탱크 를 패키지 하 였 으 며,상세 하 게 분석 한 후 블 로그 한 편 을 붙 였 습 니 다.다음은 저희 가 서버 에서 가 져 오고 분석 한 Xml 파일 입 니 다.
<?xml version="1.0" encoding="UTF-8"?>
<contacts>
<contact id="1">
<name> </name>
<image src="http://192.168.1.103:8080/mymyweb/images/1.gif"/>
</contact>
<contact id="2">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/2.gif"/>
</contact>
<contact id="3">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/3.gif"/>
</contact>
<contact id="4">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/4.gif"/>
</contact>
<contact id="5">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/5.gif"/>
</contact>
<contact id="6">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/6.gif"/>
</contact>
<contact id="7">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/7.gif"/>
</contact>
<contact id="8">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/8.gif"/>
</contact>
<contact id="9">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/9.gif"/>
</contact>
<contact id="10">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/10.gif"/>
</contact>
<contact id="11">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/11.gif"/>
</contact>
<contact id="12">
<name>dylan</name>
<image src="http://192.168.1.103:8080/myweb/images/12.gif"/>
</contact>
<contact id="13">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/13.gif"/>
</contact>
<contact id="14">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/14.gif"/>
</contact>
<contact id="15">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/15.jpg"/>
</contact>
<contact id="16">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/16.jpg"/>
</contact>
<contact id="17">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/17.jpg"/>
</contact>
<contact id="18">
<name> </name>
<image src="http://192.168.1.103:8080/myweb/images/18.jpg"/>
</contact>
</contacts>
이 demo 에 서 는 안전 을 위해 다운로드 한 그림 의 파일 이름 을 MD5 암호 화 했 습 니 다.다음은 MD5 암호 화 된 코드 입 니 다.
public class MD5 {
public static String getMD5(String content) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(content.getBytes());
return getHashString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static String getHashString(MessageDigest digest) {
StringBuilder builder = new StringBuilder();
for (byte b : digest.digest()) {
builder.append(Integer.toHexString((b >> 4) & 0xf));
builder.append(Integer.toHexString(b & 0xf));
}
return builder.toString();
}
}
이상 은 Contact.java 라 는 domain 류 를 생략 했 습 니 다.이 demo 를 통 해 안 드 로 이 드 에서 비동기 작업 을 자주 처리 해 야 한 다 는 것 을 알 수 있 습 니 다.그래서 저 희 는 수 동 으로 스 레 드,handler 체제,또는 AsyncTask 류 등 수단 으로 응용 성능 을 확보 합 니 다.위 에서 말 한 것 은 소 편 이 소개 한 안 드 로 이 드 비동기 로 그림 을 다운로드 하고 캐 시 그림 을 로 컬 DEMO 에 상세 하 게 설명 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.