Android客户端读取PHP服务器的图片等信息,并用ListView列出来,
本人第一次做客户端与服务器之间的数据交换方面的功能,所以有什么做得思路和方法不对的地方,请各位大神指教。 首先,我就是用很容易理解的方法去实现这个功能。 在服务器端,做一个index.php文件,用来读取MySQL数据库的信息: index.php: ?php $link = m
本人第一次做客户端与服务器之间的数据交换方面的功能,所以有什么做得思路和方法不对的地方,请各位大神指教。
首先,我就是用很容易理解的方法去实现这个功能。
在服务器端,做一个index.php文件,用来读取MySQL数据库的信息:
index.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
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
private static final long serialVersionUID = 1L;
protected boolean removeEldestEntry(Entry
if (size() > MAX_CAPACITY) {// 当超过一级缓存阈值的时候,将老的值从一级缓存搬到二级缓存
mSecondLevelCache.put(eldest.getKey(), new SoftReference
return true;
}
return false;
};
};
// 二级缓存,采用的是软应用,只有在内存吃紧的时候软应用才会被回收,有效的避免了oom
private ConcurrentHashMap
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
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
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;
}
}
注意在AndroidManifest.xml要做些修改:
1.添加联网许可:
2.不能出现
参考 :http://blog.sina.com.cn/s/blog_6923201d01011t6h.html
http://my.oschina.net/lhjtianji/blog/101806

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。
