网络编程(上)

1.网络访问

步骤
* 网络权限

在AndroidManifest.xml 中声明对应的权限:<uses-permission android:name="android.permission.INTERNET"/>
  • 创建URL对象
//URL的作用:统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL url = new URL(path);//path为网络请求的路径
  • 通过URL打开网络连接对象
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  • 设置网络请求的参数
conn.setRequestMethod("GET");//设置请求参数为get, 默认的请求方式就是get
conn.setConnectTimeout(5000);//设置请求服务器的超时时间
  • 得到服务器的返回信息
String type = conn.getContentType();//服务器返回的数据类型
int length = conn.getContentLength();//服务器返回的数据类型
int code = conn.getResponseCode(); // 200 OK 404 资源没找到 503服务器内部错误
  • 得到服务器返回的数据
InputStream is = conn.getInputStream()

//如果是一张图片资源的话,android提供了一个方便的API:BitmapFactory可以方便将流转为Bitmap位图图片
Bitmap bitmap = BitmapFactory.decodeStream(IO输入流);
  • useragent的使用
作用:让服务器端判断客户端是来自电脑,还是手机设备! 
设置方式:
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; InfoPath.2");
通过该设置可以服务器端认为该请求是来自电脑windows系统

2.ANR异常

Application Not Response,应用程序无响应,简称ANR 异常。
* 在主线程中做一些耗时的操作,比如网络访问、文件拷贝等阻塞了主线程,导致主线程无法响应,这时就会报ANR 异常。因此对于耗时操作,必须在子线程中完成。

3.主线程不能访问网络

Google 工程师考虑到网络访问是一个比较耗时的操作,从Android 4.0 开始,Google 更加在意UI 界面运行的流畅性,强制要求访问网络的操作不允许在主线程中执行,只能在子线程中进行,在主线程请求网络时,会报如下错误:android.os.NetworkOnMainThreadException
因此,访问网络的操作必须在子线程中进行。

4.子线程不能修改UI

主线程也叫UI 线程,Activity 中的onCreate 方法和点击事件的方法都是运行在主线程中的。主线程创建的界面,因此只有主线程才能修改界面,别的线程不允许修改,否则会报如下错误:

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

5.示例代码

//网络图片查看器

//获取位图的方法 
public Bitmap getBitmap(String path)throw Exception{
    // 1.得到图片的url路径
    URL url = new URL(path);
    // 2.通过路径打开一个http的连接
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");//设置请求参数为get, 默认的请求方式就是get
    conn.setConnectTimeout(5000);//设置请求服务器的超时时间.
    // 3.得到服务器的返回信息
    int code = conn.getResponseCode(); // 200 OK 404 资源没找到 503服务器内部错误
    if (code == 200) {
        //请求成功
        InputStream is = conn.getInputStream();
        Bitmap bitmap = BitmapFactory.decodeStream(is);
        is.close();
        return bitmap;//成功返回图片
    }else{
        return null;//失败返回null
    }
}
//事件绑定的方法,使用子线程获取网络图片
public void viewImage(View view) {
    final String path = et_path.getText().toString().trim();
    if (TextUtils.isEmpty(path)) {
        Toast.makeText(this, "对不起,图片路径不能为空", 0).show();
        return;
    }
    new Thread(){
        public void run() {
            try {
                Bitmap bitmap=getBitmap(path);
                //不能直接更新ui,通过发消息让handler去更新ui
                Message msg = Message.obtain();//节约了内存
                msg.what = SUCCESS;//what标识一个消息的类型
                msg.obj = bitmap;
                handler.sendMessage(msg);
            catch (Exception e) {
                e.printStackTrace();
                Message msg = Message.obtain();
                msg.what = ERROR;
                handler.sendMessage(msg);
            }
        }
    }.start();
}

//子线程发送消息更新UI,在handler中处理消息
private Handler handler = new Handler(){
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
            case SUCCESS:
                Bitmap bitmap = (Bitmap) msg.obj;
                iv.setImageBitmap(bitmap);
            break;
                case ERROR:
                Toast.makeText(MainActivity.this, "获取图片失败", 0).show();
            break;
        }
    }
};

6.中文乱码

  • 常见的黑色菱形里面带问号乱码造成的原因: gbk的数据 以utf-8方式显示.
  • 只要保证服务器端和客户端的编码同一就可以解决乱码问题.
  • 客户端可以根据服务器端返回的数据中包含哪种编码来对应解码:
public class StreamTools {
    public static String readStream(InputStream is) throws Exception{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while((len = is.read(buffer))!=-1){
            baos.write(buffer, 0, len);
        }
        is.close();
        String temp = baos.toString();

        if(temp.contains("charset=utf-8")){
            return temp;
        }else if(temp.contains("gb2312")){
            return baos.toString("gb2312");
        }return null;
    }
}

7.JSON

1.JSON的定义:

一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。

  • 业内主流技术为其提供了完整的解决方案(有点类似于正则表达式,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。

2.JSON Vs XML

  • JSON和XML的数据可读性基本相同
  • JSON和XML同样拥有丰富的解析手段
  • JSON相对于XML来讲,数据的体积小
  • JSON与JavaScript的交互更加方便
  • JSON对数据的描述性比XML较差
  • JSON的速度要远远快于XML

3.JSONObject

可以看作是一个json对象,这是系统中有关JSON定义的基本单元,其包含一对儿(Key/Value)数值。

Json字符串中凡是一对{}的数据都可以封装成一个JSONObject对象来进行解析,JSONObject可以方便的根据key值来取出vaule值。

4.JSONArray

可以看做是一个json数组对象,里面装的是一个一个的JSONOject对象,通过角标JSONArray. getJSONObject (index)取出对应的JSONOject对象。

Json字符串中凡是一对[]的数据都可以封装成JSONArray数组。

8.自定义SmartImageView

public class SmartImageView extends ImageView {

    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            Bitmap bitmap = (Bitmap) msg.obj;
            setImageBitmap(bitmap);
        };
    };

    public SmartImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public SmartImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SmartImageView(Context context) {
        super(context);
    }
    /**
     * 设置一个网络的图片路径,直接把网络上的图片给显示出来
     * @param url
     */
    public void setImageUrl(final String path){
        new Thread(){
            public void run() {
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setConnectTimeout(5000);
                    int code = conn.getResponseCode();
                    if(code == 200){
                        InputStream is = conn.getInputStream();
                        Bitmap bitmap = BitmapFactory.decodeStream(is);
                        Message msg = Message.obtain();
                        msg.obj = bitmap;
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值