Android(5)——网络操作

Android

安卓开发者指南:https://developer.android.google.cn/guide

1 网络操作

1.1 Android中的网络操作

Android程序最重要的模块就是网络部分,如何从网络上下载数据,如何将处理过的数据上传至网络,往往是android程序的关键环节。
Android网络多半数是基于移动端的开发,那么这时候我们所开发的app就要不断的向服务器端发送请求,然后服务器端会根据相应的请求字段将相应的内容返回给app端,这时候返回给app端的是json格式的字符串,然后app端通过一定的json解析手段将一定的数据显示在对应的控件上,达到数据显示的效果。

  1. 客户端与服务端

  2. Http协议(超文本传输协议Hypertext Transfer Protocol,应用层),是web联网的基础,也是手机联网常用的协议之一, HTTP协议是建立在TCP协议之上的一种应用。HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。HTTP提供了封装或者显示数据的具体形式,Socket 提供了网络通信的能力。
    HTTPS (全称: Hypertext Transfer Protocol over Secure Socket Layer ),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。它是一 个URI scheme (抽象标识符体系),句法类同http:体系,用于安全的HTTP数据传输。https:URL 表明它使用了HTTP但HTTssPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

  3. URL解析
    协议、域名、端口、虛拟目录、参数…

从服务器获取数据
1.实例化一个URL对象
5. 获取HttpURLConnection对象
3.设置请求连接属性
4.获取响应码,判断连接结果码
5.读取输入流并解析

get VS post
在这里插入图片描述
get请求
在这里插入图片描述
会出现闪退,解决方案:
利用多线程,操作网络在主线程就会闪退,在子线程不会,但是更新主线程UI也会闪退,使用runOnUiThread。(主线程跳子线程,再跳回主线程,很麻烦,但是会有一些耗时操作,在子线程做一些耗时操作,最后在主线程更新)

new Thread(new Runable() {
	public void run() {
		try{
			URL url = new URL
			......
			if(responseCode == HttpURLConnection.HTTP_ OK){ 
				InputStream inputStream = connect ion getInputStream() ;
				mResult = streamToString(inputStream);// String mResult全局变量
				runOnUiThread(new Runnable(){
					@Override
					public void run(){
						mResult = decode(mResult);
						mTextView.setText(mResult ); 
					}
				});
			} else {
				Log.e(TAG, "run:error code:" + responseCode+",message:"+responseMessage);
			}
		}
	}
}

在AndroidManifest.xml中申请Internet网络权限

<uses-permission android:name="android.permission.INTERNET"/>

API 28(Android 9.0)新特性
9.0对http请求的限制。在Android9.0版本中,对网络安全有较高的要求,如果访问的是https协议则不受影响;而如果访问了http协议的网址,还需要添加安全配置文件,步骤如下:

1.创建安全配置文件:
在res文件夹下创建文件夹xml,network-security-config文件
增加cleartextTrafficPermitted属性(允许http请求)

<network-security-config>
	<base-config cleartextTrafficPermitted = "true"/>
</network-security-config>

2.添加安全配置文件
在AndroidManifest.xml中的application声明添加:
android:networkSecurityConfig="@xml/network-security-config"

post请求
在这里插入图片描述
登录注册大多是用的post请求(get简单,但是不安全)

1.2 JSON数据解析
  1. JSON数据解析
    JSON数据格式是什么:
    一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式, 获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。
    在这里插入图片描述

  2. 使用JSONObject解析JSON数据

  3. 使用GSON解析JSON数据

demo代码:

public class NetworkActivity extends AppCompatActivity implements View.OnClickListener{
    private TextView mTextView;
    private Button mButton;
    private static final String TAG = "NetworkActivity";
    private String mResult;
    private Button mParseDataButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_network);
        findViews();
        setListeners();
    }
    private void findViews() {
        mTextView = findViewById(R.id.textView);
        mButton = findViewById(R.id.getButton);
        mParseDataButton = findViewById(R.id.parseDataButton);
    }
    private void setListeners() {
        mButton.setOnClickListener(this);
        mParseDataButton.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.getButton:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String urlString = "http://www.imooc.com/api/teacher?type=2&page=1";
                        mResult = requestDataByGet(urlString);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mResult = decode(mResult);
                                mTextView.setText(mResult);
                            }
                        });
                    }
                }).start();
                break;
            case R.id.parseDataButton:
                if (!TextUtils.isEmpty(mResult)) {
                    handleJSONData(mResult);
                }
                break;
        }
    }
    private void handleJSONData(String json) {
        try {
            JSONObject jsonObject = new JSONObject(json);
            LessonResult lessonResult = new LessonResult();
            List<LessonResult.Lesson> lessonList = new ArrayList<>();
            int status = jsonObject.getInt("status");
            JSONArray lessons = jsonObject.getJSONArray("data");
            if (lessons != null && lessons.length() > 0) {
                for (int index = 0; index < lessons.length(); index++) {
                    JSONObject item = (JSONObject) lessons.get(0);
                    int id = item.getInt("id");
                    String name = item.getString("name");
                    String smallPic = item.getString("picSmall");
                    String bigPic = item.getString("picBig");
                    String description = item.getString("description");
                    int learner = item.getInt("learner");
                    LessonResult.Lesson lesson = new LessonResult.Lesson();
                    lesson.setID(id);
                    lesson.setName(name);
                    lesson.setSmallPictureUrl(smallPic);
                    lesson.setBigPictureUrl(bigPic);
                    lesson.setDescription(description);
                    lesson.setLearnerNumber(learner);
                    lessonList.add(lesson);
                }
                lessonResult.setStatus(status);
                lessonResult.setLessons(lessonList);
                mTextView.setText("data is : " + lessonResult.toString());
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    private String requestDataByGet(String urlString) {
        String result = null;
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(30000);
            connection.setRequestMethod("GET");  // GET POST
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Charset", "UTF-8");
            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.connect();
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                result = streamToString(inputStream);
            } else {
                String responseMessage = connection.getResponseMessage();
                Log.e(TAG, "requestDataByPost: " + responseMessage);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 将输入流转换成字符串
     * @param is 从网络获取的输入流
     * @return 字符串
     */
    public String streamToString(InputStream is) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            baos.close();
            is.close();
            byte[] byteArray = baos.toByteArray();
            return new String(byteArray);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
            return null;
        }
    }
    /**
     * 将Unicode字符转换为UTF-8类型字符串
     */
    public static String decode(String unicodeStr) {
        if (unicodeStr == null) {
            return null;
        }
        StringBuilder retBuf = new StringBuilder();
        int maxLoop = unicodeStr.length();
        for (int i = 0; i < maxLoop; i++) {
            if (unicodeStr.charAt(i) == '\\') {
                if ((i < maxLoop - 5)
                        && ((unicodeStr.charAt(i + 1) == 'u') || (unicodeStr
                        .charAt(i + 1) == 'U')))
                    try {
                        retBuf.append((char) Integer.parseInt(unicodeStr.substring(i + 2, i + 6), 16));
                        i += 5;
                    } catch (NumberFormatException localNumberFormatException) {
                        retBuf.append(unicodeStr.charAt(i));
                    }
                else {
                    retBuf.append(unicodeStr.charAt(i));
                }
            } else {
                retBuf.append(unicodeStr.charAt(i));
            }
        }
        return retBuf.toString();
    }
    private String requestDataByPost(String urlString) {
        String result = null;
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(30000);
            connection.setRequestMethod("POST");
            // 设置运行输入,输出:
            connection.setDoOutput(true);
            connection.setDoInput(true);
            // Post方式不能缓存,需手动设置为false
            connection.setUseCaches(false);
            connection.connect();
            // 我们请求的数据:
            String data = "username=" + URLEncoder.encode("imooc", "UTF-8")
                    + "&number=" + URLEncoder.encode("15088886666", "UTF-8");
            // 获取输出流
            OutputStream out = connection.getOutputStream();
            out.write(data.getBytes());
            out.flush();
            out.close();
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                Reader reader = new InputStreamReader(inputStream, "UTF-8");
                char[] buffer = new char[1024];
                reader.read(buffer);
                result = new String(buffer);
                reader.close();
            } else {
                String responseMessage = connection.getResponseMessage();
                Log.e(TAG, "requestDataByPost: " + responseMessage);
            }
            final String finalResult = result;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mTextView.setText(finalResult);
                }
            });
            connection.disconnect();
            return result;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值