展会信息港展会大全

Android客户端读取PHP服务器的图片等信息,并用ListView列出来,实现缓存功能。
来源:互联网   发布日期:2015-11-26 14:14:17   浏览:5718次  

导读:首先,我就是用很容易理解的方法去实现这个功能。在服务器端,做一个index.php文件,用来读取MySQL数据库的信息:index.php:<?php$link = mysql_con...

首先,我就是用很容易理解的方法去实现这个功能。

在服务器端,做一个index.php文件,用来读取MySQL数据库的信息:

index.php:

<?php

$link = mysql_connect("localhost", "root", "123456");

mysql_query("SET NAMES utf8");

mysql_select_db("test", $link);//test为数据库名

$sql = mysql_query("select * from interp_images ", $link);//interp_images 为表名

while ($row = mysql_fetch_assoc($sql))

$output[] = $row;

print (json_encode($output));

mysql_close();

?>

这个PHP文件执行得到的是从数据库表读取出来的所在数据数组。

程序的主代码的一些详解:

ListViewPerformaceActivity .java:

public class ListViewPerformaceActivity extends Activity {

protected static final String TAG = "ListViewPerformaceActivity";

/** Called when the activity is first created. */

private ListView mListview;

ImageLoader mImageLoader = new ImageLoader();

MyAdapter adapter;

private JSONArray jArray;

private String result = null;

private InputStream is = null;

private StringBuilder sb = null;

//private ListView mListView;

private View mView;

private String imageUrl;

private String imageDetailUrl;

private int ct_id;

private String ct_name;

private String ct_detail_name;

private JSONObject json_data = null;

private String[] fileUrl;

private String[] detailUrl;

private int count;

private Bitmap bitmap;

private byte buff[] = new byte[1024 * 250];

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

// TODO http get

try {

HttpClient httpclient = new DefaultHttpClient();

HttpGet httpget = new HttpGet("http://192.168.18.29/Test/index.php");//IP为自己的服务器的IP因为手机连接局域网的WIFI,所以只用自己的电脑作为服务器也可以测试效果。

HttpResponse response = httpclient.execute(httpget);

HttpEntity entity = response.getEntity();

is = entity.getContent();

} catch (Exception e) {

Log.e("log_tag", "2013Error in http connection" + e.toString());

}

// convert response to string

try {

BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);

sb = new StringBuilder();

sb.append(reader.readLine() + "\n");

String line = "0";

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

sb.append(line + "\n");

}

is.close();

result = sb.toString();

} catch (Exception e) {

e.printStackTrace();

Log.e("log_tag", "Error converting result " + e.toString());

}

// /////////////////////////////////////////////////////////////////////////////

// paring data

try {

jArray = new JSONArray(result);

// JSONObject json_data = null;

count = 0;

detailUrl = new String[jArray.length()];

fileUrl = new String[jArray.length()];

for (int i = 0; i < jArray.length(); i++) {//把读取到数据库表的数据通过for循环添加到数组里

json_data = jArray.getJSONObject(i);

ct_id = json_data.getInt("categoryid");

ct_name = json_data.getString("androidfilename");

imageUrl = "http://192.168.18.29/Test/MyWebsiteImages/2013_07_to7szt75poNC/760x760/" + ct_name; //这里只是把服务器上的图片路径写死了

fileUrl[count] = imageUrl;

ct_detail_name = json_data.getString("filename");

imageDetailUrl = "http://192.168.18.29/Test/MyWebsiteImages/2013_07_to7szt75poNC/760x760/"

+ ct_detail_name;

detailUrl[count] = imageDetailUrl;

count++;

}

} catch (JSONException e1) {

e1.printStackTrace();

} catch (ParseException e1) {

e1.printStackTrace();

}

setupViews();

}

private void setupViews() {

mListview = (ListView) findViewById(R.id.main_lv_list);

adapter = new MyAdapter(fileUrl, count, this);//这里把从数据库读取出来的图片URL传给Adapter

mListview.setAdapter(adapter);

mListview.setOnScrollListener(mScrollListener);

// 添加ListView中Item的点击事件,针对整个Item,如果Item布局不同的组件,对不同的组件添加不同的事件,刚要另外处理,我实现了这个功能,这里就不多说,可以自己再找资料研究。

mListview.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

setTitle("点击第" + arg2 + "列" );

// bitmap = getBitmap(detailUrl[arg2]);

//

// buff = Bitmap2Bytes(bitmap);

// Intent mIntent = new Intent();

// mIntent.putExtra("image", buff);

// mIntent.setClass(ZhiXunActivity.this,

// ZhiXunDetailActivity.class);

// startActivity(mIntent);

}

});

}

OnScrollListener mScrollListener = new OnScrollListener() {//加载图片的缓存处理

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

switch (scrollState) {

case OnScrollListener.SCROLL_STATE_FLING:

adapter.setFlagBusy(true);

break;

case OnScrollListener.SCROLL_STATE_IDLE:

adapter.setFlagBusy(false);

break;

case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:

adapter.setFlagBusy(false);

break;

default:

break;

}

adapter.notifyDataSetChanged();

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

}

};

}

ImageLoader .java:

public class ImageLoader {

private static final String TAG = "ImageLoader";

private static final int MAX_CAPACITY = 10;// 一级缓存的最大空间

private static final long DELAY_BEFORE_PURGE = 10 * 1000;// 定时清理缓存

// 0.75是加载因子为经验值,true则表示按照最近访问量的高低排序,false则表示按照插入顺序排序

private HashMap<String, Bitmap> mFirstLevelCache = new LinkedHashMap<String, Bitmap>(MAX_CAPACITY / 2, 0.75f, true) {

private static final long serialVersionUID = 1L;

protected boolean removeEldestEntry(Entry<String, Bitmap> eldest) {

if (size() > MAX_CAPACITY) {// 当超过一级缓存阈值的时候,将老的值从一级缓存搬到二级缓存

mSecondLevelCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));

return true;

}

return false;

};

};

// 二级缓存,采用的是软应用,只有在内存吃紧的时候软应用才会被回收,有效的避免了oom

private ConcurrentHashMap<String, SoftReference<Bitmap>> mSecondLevelCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(

MAX_CAPACITY / 2);

// 定时清理缓存

private Runnable mClearCache = new Runnable() {

@Override

public void run() {

clear();

}

};

private Handler mPurgeHandler = new Handler();

// 重置缓存清理的timer

private void resetPurgeTimer() {

mPurgeHandler.removeCallbacks(mClearCache);

mPurgeHandler.postDelayed(mClearCache, DELAY_BEFORE_PURGE);

}

/**

* 清理缓存

*/

private void clear() {

mFirstLevelCache.clear();

mSecondLevelCache.clear();

}

/**

* 返回缓存,如果没有则返回null

*

* @param url

* @return

*/

public Bitmap getBitmapFromCache(String url) {

Bitmap bitmap = null;

bitmap = getFromFirstLevelCache(url);// 从一级缓存中拿

if (bitmap != null) {

return bitmap;

}

bitmap = getFromSecondLevelCache(url);// 从二级缓存中拿

return bitmap;

}

/**

* 从二级缓存中拿

*

* @param url

* @return

*/

private Bitmap getFromSecondLevelCache(String url) {

Bitmap bitmap = null;

SoftReference<Bitmap> softReference = mSecondLevelCache.get(url);

if (softReference != null) {

bitmap = softReference.get();

if (bitmap == null) {// 由于内存吃紧,软引用已经被gc回收了

mSecondLevelCache.remove(url);

}

}

return bitmap;

}

/**

* 从一级缓存中拿

*

* @param url

* @return

*/

private Bitmap getFromFirstLevelCache(String url) {

Bitmap bitmap = null;

synchronized (mFirstLevelCache) {

bitmap = mFirstLevelCache.get(url);

if (bitmap != null) {// 将最近访问的元素放到链的头部,提高下一次访问该元素的检索速度(LRU算法)

mFirstLevelCache.remove(url);

mFirstLevelCache.put(url, bitmap);

}

}

return bitmap;

}

/**

* 加载图片,如果缓存中有就直接从缓存中拿,缓存中没有就下载

*

* @param url

* @param adapter

* @param holder

*/

public void loadImage(String url, BaseAdapter adapter, ViewHolder holder) {

resetPurgeTimer();

Bitmap bitmap = getBitmapFromCache(url);// 从缓存中读取

if (bitmap == null) {

holder.mImageView.setImageResource(R.drawable.ic_launcher);// 缓存没有设为默认图片

ImageLoadTask imageLoadTask = new ImageLoadTask();

imageLoadTask.execute(url, adapter, holder);

} else {

holder.mImageView.setImageBitmap(bitmap);// 设为缓存图片

}

}

/**

* 放入缓存

*

* @param url

* @param value

*/

public void addImage2Cache(String url, Bitmap value) {

if (value == null || url == null) {

return;

}

synchronized (mFirstLevelCache) {

mFirstLevelCache.put(url, value);

}

}

class ImageLoadTask extends AsyncTask<Object, Void, Bitmap> {

String url;

BaseAdapter adapter;

@Override

protected Bitmap doInBackground(Object... params) {

url = (String) params[0];

adapter = (BaseAdapter) params[1];

Bitmap drawable = loadImageFromInternet(url);// 获取网络图片

return drawable;

}

@Override

protected void onPostExecute(Bitmap result) {

if (result == null) {

return;

}

addImage2Cache(url, result);// 放入缓存

adapter.notifyDataSetChanged();// 触发getView方法执行,这个时候getView实际上会拿到刚刚缓存好的图片

}

}

public Bitmap loadImageFromInternet(String url) {

Bitmap bitmap = null;

HttpClient client = AndroidHttpClient.newInstance("Android");

HttpParams params = client.getParams();

HttpConnectionParams.setConnectionTimeout(params, 3000);

HttpConnectionParams.setSocketBufferSize(params, 3000);

HttpResponse response = null;

InputStream inputStream = null;

HttpGet httpGet = null;

try {

httpGet = new HttpGet(url);

response = client.execute(httpGet);

int stateCode = response.getStatusLine().getStatusCode();

if (stateCode != HttpStatus.SC_OK) {

Log.d(TAG, "func [loadImage] stateCode=" + stateCode);

return bitmap;

}

HttpEntity entity = response.getEntity();

if (entity != null) {

try {

inputStream = entity.getContent();

return bitmap = BitmapFactory.decodeStream(inputStream);

} finally {

if (inputStream != null) {

inputStream.close();

}

entity.consumeContent();

}

}

} catch (ClientProtocolException e) {

httpGet.abort();

e.printStackTrace();

} catch (IOException e) {

httpGet.abort();

e.printStackTrace();

} finally {

((AndroidHttpClient) client).close();

}

return bitmap;

}

}

MyAdapter.java:

public class MyAdapter extends BaseAdapter {

private static final String TAG = "MyAdapter";

private boolean mBusy = false;

public void setFlagBusy(boolean busy) {

this.mBusy = busy;

}

private ImageLoader mImageLoader;

private int mCount;

private Context mContext;

String[] URLS;

public MyAdapter(String[] URLS, int count, Context context) {

this.URLS=URLS;

this.mCount = count;

this.mContext = context;

mImageLoader = new ImageLoader();

}

@Override

public int getCount() {

return mCount;

}

@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) {

Log.d(TAG, "position=" + position + ",convertView=" + convertView);

ViewHolder viewHolder = null;

if (convertView == null) {

convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, null);// 这个过程相当耗时间

viewHolder = new ViewHolder();

viewHolder.mTextView = (TextView) convertView.findViewById(R.id.tv_tips);

viewHolder.mImageView = (ImageView) convertView.findViewById(R.id.iv_image);

convertView.setTag(viewHolder);

} else {

viewHolder = (ViewHolder) convertView.getTag();

}

String url = "";

url = URLS[position % URLS.length];

if (!mBusy) {

mImageLoader.loadImage(url, this, viewHolder);

viewHolder.mTextView.setText("--" + position + "--IDLE ||TOUCH_SCROLL");

} else {

Bitmap bitmap = mImageLoader.getBitmapFromCache(url);

if (bitmap != null) {

viewHolder.mImageView.setImageBitmap(bitmap);

} else {

viewHolder.mImageView.setImageResource(R.drawable.ic_launcher);

}

viewHolder.mTextView.setText("--" + position + "--FLING");

}

return convertView;

}

static class ViewHolder {

TextView mTextView;

ImageView mImageView;

}

}

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港