前言
web开发有前段与后端之分,其实android也有前后端之分。android开发就相当于手机App的前端。一般都是php+android或者jsp+android开发,所以作为一个合格的android开发人员我们还是有必要了解一下android与后端的简单交互。下面是以php+android交互的简单介绍。
PHP数据接口的定义
php端的开发主要是实现从数据库获取数据,然后将数据制定成json类型,制定供android获取的接口。至于为什么制定成json类型,相信大家都明白,现在android端从服务器中获取的数据都是以json的格式封装的。好了下面开始操作。
数据库表的建立
首先建表定义好提供请求的数据,简单点,上张图:
数据库的连接
建完表后我们就开始在PHP中连接数据库,以pdo的连接方式为例
<?php
/**
* 连接数据库
*/
try{
$pdo = new PDO("mysql:host=localhost:3306;dbname=blog;","root","666666");
//设置编码
$pdo->exec("set names utf8");
}catch(PDOException $e){
die("数据库连接失败".$e->getMessage());
}
?>
只要传入本地端口,数据库名,用户名,密码即可。
获取与制定json
连接数据库成功后,就可以遍历表获取所有数据
$sql = "SELECT * FROM blog";
查询与遍历
$stmt = $pdo->query($sql);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$list["blog"][] = $row;
}
最后将获取到的数据转封装成json类型
print_r(json_encode($list));
用浏览器访问后的数据就是json类型了,我这里访问的是:http://192.168.56.1/WebBlog/j...p"(根据自己本机的ip地址与项目地址)
好了PHP端的就可以到这里结束了,下面进入android端
Android端数据获取
Android端主要的是json实体类的建立与从我们上面定义的借口获取数据,所以这里要用到网络请求,获取数据,然后在显示出来,下面简单的介绍下。
Json实体类的定义
这里主要推荐一个工具,把GsonFormat集成到AS中,可以很方便的生成实体类。如果不使用的话,就要根据前面定义的数据类型来进行一一对应。下面是我按上面的类型定义的实体类
private List<BlogBean> blog;
public List<BlogBean> getBlog() {
return blog;
}
public void setBlog(List<BlogBean> blog) {
this.blog = blog;
}
public static class BlogBean {
private String id;
private String title;
private String time;
private String content_url;
private String image_url;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getContent_url() {
return content_url;
}
public void setContent_url(String content_url) {
this.content_url = content_url;
}
public String getImage_url() {
return image_url;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
自定义GsonRequest
我们使用volley与gson来解析json数据,首先我先自定义GsonRequest,这里需要继承volley的Request
public class GsonRequest<T> extends Request<T> {
private Class<T> mClass;
private final Response.Listener<T> mListener;
private Gson mGson;
private List<T> mList;
public GsonRequest(int method, String url, Class<T> tClass, Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
mClass = tClass;
mListener = listener;
mGson = new Gson();
}
public GsonRequest(String url, Class<T> tClass, Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(Method.GET, url, tClass, listener, errorListener);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse networkResponse) {
try {
mList = new ArrayList<>();
String jsonString = new String(networkResponse.data,
HttpHeaderParser.parseCharset(networkResponse.headers));
return Response.success(mGson.fromJson(jsonString, mClass),
HttpHeaderParser.parseCacheHeaders(networkResponse));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T t) {
mListener.onResponse(t);
}
}
Volley网络请求数据
使用我们上面自定义的GsonRequest来请求数据
String url = "http://192.168.56.1/WebBlog/json/getBlogJson.php";
GsonRequest<BlogInfo> gsonRequest = new GsonRequest<BlogInfo>(url, BlogInfo.class, new Response.Listener<BlogInfo>() {
@Override
public void onResponse(BlogInfo info) {
mList = info.getBlog();
BlogAdapter mAdapter = new BlogAdapter(MainActivity.this,mList,R.layout.blog_item);
blogLv.setAdapter(mAdapter);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("TAG", volleyError.getMessage(), volleyError);
}
});
//添加到请求队列中
RequestManager.addRequest(gsonRequest, "blogRequest");
数据在onResponse中请求到了,存储到List集合中,通过设置adapter显示获取的数据,这里就不展开adapter的使用
网络请求图片与缓存
还是说下网络请求图片与图片的缓存处理,也是通过volley的实现,所以我们可以一套的使用volley就可以实现许多基本的网络请求。
使用到的是LruCache,所以我可以继承它
@Override
protected int sizeOf(String key, Bitmap value) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB_MR1){
return value.getByteCount();
}
return value.getRowBytes() * value.getHeight();
}
@Override
public Bitmap getBitmap(String s) {
return get(s);
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
put(s,bitmap);
}
然后再自定义ImageCacheManager
public class ImageCacheManager {
private static final int CACHE_SIZE = 1024 * 1024 * ((ActivityManager) App.getAppContext()
.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass() / 8;
public ImageCacheManager() {
}
private static ImageLoader mImageLoader = new ImageLoader(RequestManager.mRequestQueue, new BitmapLruCache(CACHE_SIZE));
public static ImageLoader.ImageContainer loadImage(String requestUrl, ImageLoader.ImageListener listener, int maxWidth, int maxHeight) {
return mImageLoader.get(requestUrl, listener, maxWidth, maxHeight);
}
public static ImageLoader.ImageContainer loadImage(String requestUrl, ImageLoader.ImageListener listener) {
return loadImage(requestUrl, listener, 0, 0);
}
public static ImageLoader.ImageListener getImageListener(final ImageView view, final Drawable defaultImageDrawable, final Drawable errorImageDrawable) {
return new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) {
if (imageContainer.getBitmap() != null) {
if (!b && defaultImageDrawable != null) {
TransitionDrawable transitionDrawable = new TransitionDrawable(
new Drawable[]{defaultImageDrawable
, new BitmapDrawable(App.getAppContext().getResources(), imageContainer.getBitmap())}
);
transitionDrawable.setCrossFadeEnabled(true);
view.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(100);
} else {
view.setImageBitmap(imageContainer.getBitmap());
}
} else if (defaultImageDrawable != null) {
view.setImageDrawable(defaultImageDrawable);
}
}
@Override
public void onErrorResponse(VolleyError volleyError) {
if (errorImageDrawable != null) {
view.setImageDrawable(errorImageDrawable);
}
Log.e("TAG",volleyError.getMessage());
}
};
}
}
最后就可以通过使用ImageCacheManager来加载网络图片与缓存图片
ImageCacheManager.loadImage(mList.get(position).getImage_url()
, ImageCacheManager.getImageListener((ImageView) holder.getView(R.id.item_image)
, App.getAppContext().getResources().getDrawable(R.drawable.blog_default), App.getAppContext().getResources().getDrawable(R.drawable.blog_default))
,0,0);
当然volley的网络请求不止这些,就拿图片的请求,还有直接使用ImageRequest与NetworkImageView,本来还想说点webview的一点知识,今天有点晚,在宿舍要断电断网了,就不展开了。
还是执行我一贯的做法上张效果图吧
效果图
个人技术分享:https://idisfkj.github.io