Android用戶端讀取PHP伺服器的圖片等資訊,並用ListView列出來,實現緩衝功能。

來源:互聯網
上載者:User

首先,我就是用很容易理解的方法去實現這個功能。

在伺服器端,做一個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;
}


}

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.