php与android的简单交互

395 查看


前言

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

我们使用volleygson来解析json数据,首先我先自定义GsonRequest,这里需要继承volleyRequest

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的网络请求不止这些,就拿图片的请求,还有直接使用ImageRequestNetworkImageView,本来还想说点webview的一点知识,今天有点晚,在宿舍要断电断网了,就不展开了。
还是执行我一贯的做法上张效果图吧

效果图

个人技术分享:https://idisfkj.github.io