您的位置:首页 > 理论基础 > 计算机网络

AsyncTask 安卓的异步访问网络

2016-05-17 15:20 295 查看

使用 syncTask 进行网络获取图片,展示在Listview中,并且对Listview加载图片使用LruCache<>对图片进行加载缓存和滑动Listview卡屏的优化

这是自己定义的一个类,用于接收字段和图片信息

public class NewBean {

String newscinUrl; //图片

String newsTitle;//

String newsConten;

}

这是listview中的自定义的一个适配器,滑动卡屏的解决方法也是在这进行判断

package com.example.android_asynctask2;

import java.net.ContentHandler;

import java.util.List;

import android.R.layout;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AbsListView;

import android.widget.AbsListView.OnScrollListener;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;

public class NewsAdapter extends BaseAdapter implements OnScrollListener{

private List<NewBean> newlist;

private LayoutInflater mInflater;

private int mstart , mend;

public static String[] URLS;

private ImageLoader mImageLoader ;

private boolean mFirst ;

public NewsAdapter(Context context , List<NewBean> data,ListView listView){

newlist = data ;

mInflater = LayoutInflater.from(context);

mImageLoader = new ImageLoader(listView);

URLS = new String[data.size()];

for (int i = 0; i < data.size(); i++) {

URLS[i] = data.get(i).newscinUrl;

}

mFirst = true;

//一定要注册对应的数据

listView.setOnScrollListener(this);

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return newlist.size();

}

@Override

public Object getItem(int arg0) {

// TODO Auto-generated method stub

return newlist.get(arg0);

}

@Override

public long getItemId(int arg0) {

// TODO Auto-generated method stub

return arg0;

}

@Override

public View getView(int position, View conterview, ViewGroup parent) {

// TODO Auto-generated method stub

ViewHolder holder=null;

if(conterview == null){

holder = new ViewHolder();

conterview = mInflater.inflate(R.layout.item_layout, null);

holder.ivIvon = (ImageView) conterview.findViewById(R.id.image_iteam);

holder.title = (TextView) conterview.findViewById(R.id.Title);

holder.content = (TextView) conterview.findViewById(R.id.Content);

conterview.setTag(holder);

}else{

holder =(ViewHolder) conterview.getTag();

}

holder.ivIvon.setImageResource(R.drawable.bb);

//在多线加载中 baseadapter 为imageview设置一个 tag url,防止listview中图片的多次缓存问题

String url = newlist.get(position).newscinUrl;

holder.ivIvon.setTag(url);

mImageLoader.showImageByAsycTask(holder.ivIvon,url); //异步加载

// new ImageLoader().showImageByThread(holder.ivIvon,

// newlist.get(position).newscinUrl); //多线程加载

holder.title.setText("标题");

holder.content.setText("内容");

return conterview;

}

class ViewHolder{

public TextView title , content ;

public ImageView ivIvon;

}

@Override

public void onScroll(AbsListView arg0, int firstVisibleItem, int tVisibleItem, int arg3) {

// TODO Auto-generated method stub

mstart = firstVisibleItem; //第一个可见元素 tVisibleItem 可见元素长度

mend = firstVisibleItem + tVisibleItem ;

//第一次显示的时候调用

if (mFirst && tVisibleItem > 0) { //tVisibleItem 初始为0

mImageLoader.loadImages(mstart, mend);

mFirst = false ;

}

}

@Override

public void onScrollStateChanged(AbsListView arg0, int scrollState) {

// TODO Auto-generated method stub

if (scrollState == SCROLL_STATE_IDLE) {//当前listview的滚动状态

//加载可见项

mImageLoader.loadImages(mstart, mend);

}else {

//停止任务

mImageLoader.canceAllTasks();

}

}

}

这是对于listview控件上加载的图片的进行的处理,有网络获取图片和对图片缓存的处理的方法

public class ImageLoader {

private ImageView imageView;

private String mUrl;

//创建一个cache

private LruCache<String, Bitmap> mCache;

public static ListView mlistView;

private Set<AsyncTaskImageLoader> mTask;

/**

* 线程中更新ui界面

*/

private Handler handler = new Handler(){

public void handleMessage(Message msg) {

if(imageView.getTag().equals(mUrl)){ // 判断对应的imageview的tag是否相同

imageView.setImageBitmap((Bitmap) msg.obj);

}

};

};

public void showImageByThread(ImageView mimageView , final String url){

// imageView = mimageView;

mUrl = url;

new Thread(){

@Override

public void run(){

// TODO Auto-generated method stub

super.run();

Bitmap bitmap = getbitmapFrimURL(url);

Message message = Message.obtain();

message.obj = bitmap;

handler.sendMessage(message);

}

}.start();

}

class AsyncTaskImageLoader extends AsyncTask<String , Void, Bitmap>{

// private ImageView mimageView ;

private String urls;

public AsyncTaskImageLoader(String url){

// mimageView = imageView;

urls = url;

}

@Override

protected Bitmap doInBackground(String... arg0) {

// TODO Auto-generated method stub

String url = arg0[0];

//网络获取图片

Bitmap bitmap = getbitmapFrimURL(url);

if (bitmap !=null) {

//缓存网络获取的图片

addBitmapTocache(url, bitmap);

}

return bitmap;

}

@Override

protected void onPostExecute(Bitmap result) {

// TODO Auto-generated method stub

super.onPostExecute(result);

if (imageView.getTag().equals(urls)) {

ImageView imageView = (ImageView) mlistView.findViewWithTag(urls);

if (imageView != null && result!=null) {

imageView.setImageBitmap(result);

}

}

mTask.remove(this);

}

}

public ImageLoader(ListView listView){

mlistView = listView;

mTask = new HashSet<AsyncTaskImageLoader>();

//获取最大可用内存

int maxMemory = (int) Runtime.getRuntime().maxMemory();

int cacheSize = maxMemory / 4 ; //需要的内存

mCache = new LruCache<String, Bitmap>(cacheSize){

@Override

protected int sizeOf(String key, Bitmap value) {

// TODO Auto-generated method stub

//在每次存入缓存的时候调用

return value.getByteCount(); //返回缓存的大小

}

};

}

//添加缓存

public void addBitmapTocache(String url ,Bitmap bitmap){

//判断缓存中是否存在,不存在则加入缓存

if (getBitmapForcache(url) == null) {

mCache.put(url, bitmap);

}

}

//读取缓存中的数据

public Bitmap getBitmapForcache(String url){

return mCache.get(url);

}

public void showImageByAsycTask(ImageView imageView , String url){

//从缓存中读取对应的图片

Bitmap bitmap = getBitmapForcache(url);

//如果缓存中没有,则网络加载,有则读取缓存

if (bitmap == null){

imageView.setImageResource(R.drawable.bb);

}else{

imageView.setImageBitmap(bitmap);

}

}

/**

* 通过URL从网络获取图片

* @param urlString

* @return

*/

public Bitmap getbitmapFrimURL(String urlString){

Bitmap bitmap;

URL url;

InputStream is=null;

try {

url = new URL(urlString);

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

is = new BufferedInputStream(connection.getInputStream());

bitmap = BitmapFactory.decodeStream(is);

connection.disconnect(); //关闭网络连接

Thread.sleep(1000);

}catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

try {

is.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return null;

}

//用来加载从start到end的所有图片

public void loadImages(int start , int end){

for (int i = start; i < end; i++) {

String url = NewsAdapter.URLS[i];

//从缓存中读取对应的图片

Bitmap bitmap = getBitmapForcache(url);

//如果缓存中没有,则网络加载

if (bitmap == null){

AsyncTaskImageLoader TaskLoader = new AsyncTaskImageLoader(url);

TaskLoader.execute(url);

mTask.add(TaskLoader);

}else{

ImageView imageView = (ImageView) mlistView.findViewWithTag(url);

imageView.setImageBitmap(bitmap);

}

}

}

public void canceAllTasks(){

if (mTask != null) {

for (AsyncTaskImageLoader task:mTask) {

task.cancel(false);//取消AsyncTaskImageLoader所有的任务

}

}

}

}

使用AsyncTask进行网络数据的获取

public class MainActivity extends Activity {

private ListView list_main;

private String URL="";//这里填写请求的http路径

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

list_main = (ListView) findViewById(R.id.image_iteam);

new AsyncTaskJson().execute(URL);

}

/**

* 网络的异步访问

* @author

*

*/

class AsyncTaskJson extends AsyncTask<String, Void, List<NewBean>>{

@Override

protected void onPostExecute(List<NewBean> result) {

// TODO Auto-generated method stub

super.onPostExecute(result);

NewsAdapter adapter=new NewsAdapter(MainActivity.this, result ,ImageLoader.mlistView);

list_main.setAdapter(adapter);

}

// doInBackground() 执行线程中的耗时操作

@Override

protected List<NewBean> doInBackground(String... arg0) {

// TODO Auto-generated method stub

return getJsonData(arg0[0]);

}

}

/**

* 将URL对应json格式数据转化为我们所封装的NesBean对象

* json格式的转化

* @param url

* @return

*/

private List<NewBean> getJsonData(String url){

List<NewBean> beans=new ArrayList<NewBean>();

try {

//获取json格式的字符串

//new URL(url).openStream() 此句功能和 url.openconnection.getInputStream()相同,可根据URL直接联网获取网络数据,简单粗暴,返回值类型为inputStream

String jsonString =readStream(new URL(url).openStream());

JSONObject jsonObject;

NewBean bean;

JSONArray array;

try {

jsonObject = new JSONObject(jsonString);

array = jsonObject.getJSONArray("data");

for (int i = 0; i < array.length(); i++) {

jsonObject = array.getJSONObject(i);

bean = new NewBean();

bean.newscinUrl = jsonObject.getString("picSmall");

bean.newsTitle = jsonObject.getString("name");

bean.newsConten = jsonObject.getString("description");

beans.add(bean);

}

} catch (JSONException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

} catch (MalformedURLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return beans;

}

/**

* 通过inputstream解析网页返回的数据

* @param is

* @return

*/

private String readStream(InputStream is){

InputStreamReader isr ;

String result="";

try {

String line="";

isr = new InputStreamReader(is,"utf-8"); //z指定字符格式

BufferedReader br = new BufferedReader(isr);//使用buffer格式读取出来

while ((line = br.readLine()) != null) {

result +=line; //将内容保存打印出来

}

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return result;

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long

// as you specify a parent activity in AndroidManifest.xml.

int id = item.getItemId();

if (id == R.id.action_settings) {

return true;

}

return super.onOptionsItemSelected(item);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: