HarmonyOS应用开发-网络请求示例 原创 精华

深开鸿
发布于 2022-2-25 09:59
浏览
8收藏

作者:杜晨阳

简介

在应用开发的过程中,网络请求是很常见的场景,其中常见是加载网络图片、访问后台接口等。在安卓系统中实现这些相信大家已经很熟悉了,
那么在鸿蒙系统中又有哪些相似与不同呢?今天给大家带来的是在鸿蒙系统中发起网络请求的使用示例,示例中包含了使用鸿蒙API完成get、post请求,加载网络图片等。

功能展示

HarmonyOS应用开发-网络请求示例-鸿蒙开发者社区

开发概述

首先,使用网络模块的相关功能时,需要请求相应的权限。
HarmonyOS应用开发-网络请求示例-鸿蒙开发者社区
添加在entry模块的config.json中
HarmonyOS应用开发-网络请求示例-鸿蒙开发者社区
权限相关配置好后,接下来看一下鸿蒙开发官网上对于网络模块开发的接口说明

鸿蒙官网网络开发文档

文档中给出了网络开发的关键接口说明及网络开发的一般步骤,
1、调用NetManager.getInstance(Context)获取网络管理的实例对象。
2、调用NetManager.getDefaultNet()获取默认的数据网络。
3、调用NetHandle.openConnection()打开一个URL。
4、通过URL链接实例访问网站。
并且提供了网络状态的监听接口addDefaultNetStatusCallback(NetStatusCallback callback)

    private final NetStatusCallback callback = new NetStatusCallback() {
        @Override
        public void onAvailable(NetHandle handle) {
           //网络可用时
        }

        @Override
        public void onBlockedStatusChanged(NetHandle handle, boolean blocked) {
           //网络状态变化时
        }
    };

下面我们来编写下完整的网络请求实例

1、get请求


 public void requestByGet() {
        LogUtils.debug("NetRequestUtils  requestByGet");
        NetManager netManager = NetManager.getInstance(null);
        if (!netManager.hasDefaultNet()) {
            LogUtils.debug("NetRequestUtils  network is null");
            return;
        }
        ThreadPoolUtil.submit(() -> {
            NetHandle netHandle = netManager.getDefaultNet();
            netManager.addDefaultNetStatusCallback(callback);
            HttpURLConnection connection = null;
            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                URL url = new URL("http://www.baidu.com");
                URLConnection urlConnection = netHandle.openConnection(url, java.net.Proxy.NO_PROXY);
                if (urlConnection instanceof HttpURLConnection) {
                    connection = (HttpURLConnection) urlConnection;
                }
                connection.setRequestMethod("GET");
                connection.connect();

                //之后可进行url的其他操作
                try (InputStream inputStream = urlConnection.getInputStream()) {
                    byte[] cache = new byte[2 * 1024];
                    int len = inputStream.read(cache);
                    while (len != -1) {
                        outputStream.write(cache, 0, len);
                        len = inputStream.read(cache);
                    }
                } catch (IOException e) {
                    LogUtils.error("NetRequestUtils inner IOException");
                }
                String result = new String(outputStream.toByteArray());
                LogUtils.debug("NetRequestUtils result:" + result);
                getUITaskDispatcher().syncDispatch(() -> Toast.show("成功发起get网络请求:" + result));
                HttpResponseCache.getInstalled().flush();
            } catch (IOException e) {
                LogUtils.error("NetRequestUtils IOException");
            }
        });
    }

2、post请求

测试发现,只需要将connection.setRequestMethod();中的参数修改成“POST"即可

connection.setRequestMethod(“POST”);

3、网络图片加载

    /**
     * 请求网络图片
     */
    public void requestNetImage() {
        ThreadPoolUtil.submit(() -> {
            String requestUrl = "https://t7.baidu.com/it/u=4162611394,4275913936&fm=193&f=GIF";
            HttpURLConnection connection = null;
            try {
                connection = getHttpURLConnection(requestUrl, "GET");
                connection.connect();
                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    //将网络请求数据转换成ImageSource
                    ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
                    ImageSource imageSource = ImageSource.create(connection.getInputStream(), srcOpts);
                    //将ImageSource转换成可以设置给image控件的PixelMap对象
                    PixelMap pixelMap = imageSource.createPixelmap(null);
                    getUITaskDispatcher().syncDispatch(() -> image.setPixelMap(pixelMap));
                }
                connection.disconnect();
            } catch (Exception e) {
                LogUtils.error("NetRequestUtilsException  requestNetImage:" + e.getMessage());
            }
        });
    }

    private HttpURLConnection getHttpURLConnection(String requestURL, String requestMethod) throws IOException {
        URL url = new URL(requestURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //设置连接超时时间
        connection.setConnectTimeout(10 * 1000);
        //设置读取服务器数据超时时间
        connection.setReadTimeout(15 * 1000);
        //设置请求方式
        connection.setRequestMethod(requestMethod);
        return connection;
    }

在加载网络图片时,connection连接成功后,获取到的是一张图片的输入流。为了将图片输入流转化成可以显示的PixelMap对象,
需要先创建ImageSource对象,再通过imageSource.createPixelmap(null)创建对应的pixelMap对象,
最终通过image.setPixelMap(pixelMap));将图片加载到屏幕上。

以下是完整代码示例:

public class NetAbilitySlice extends AbilitySlice {
    Image image;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_slice_net);
        findComponentById(ResourceTable.Id_btn_request_get).setClickedListener(component -> {
            requestByGet();
        });
        findComponentById(ResourceTable.Id_btn_request_post).setClickedListener(component -> {
            requestByPost();
        });
        findComponentById(ResourceTable.Id_btn_request_image).setClickedListener(component -> {
            requestNetImage();
        });
        image = (Image) findComponentById(ResourceTable.Id_image_neturl);
    }

    public void requestByGet() {
        LogUtils.debug("NetRequestUtils  requestByGet");
        NetManager netManager = NetManager.getInstance(null);
        if (!netManager.hasDefaultNet()) {
            LogUtils.debug("NetRequestUtils  network is null");
            return;
        }
        ThreadPoolUtil.submit(() -> {
            NetHandle netHandle = netManager.getDefaultNet();
            netManager.addDefaultNetStatusCallback(callback);
            HttpURLConnection connection = null;
            LogUtils.debug("NetRequestUtils  ThreadPoolUtil.submit");
            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                LogUtils.debug("NetRequestUtils  URL.new URL");
                URL url = new URL("http://www.baidu.com");
                URLConnection urlConnection = netHandle.openConnection(url, java.net.Proxy.NO_PROXY);
                if (urlConnection instanceof HttpURLConnection) {
                    connection = (HttpURLConnection) urlConnection;
                }
                connection.setRequestMethod("GET");
                connection.connect();
                LogUtils.debug("NetRequestUtils  connection.connect");
                //之后可进行url的其他操作
                try (InputStream inputStream = urlConnection.getInputStream()) {
                    byte[] cache = new byte[2 * 1024];
                    int len = inputStream.read(cache);
                    while (len != -1) {
                        outputStream.write(cache, 0, len);
                        len = inputStream.read(cache);
                    }
                } catch (IOException e) {
                    LogUtils.error("NetRequestUtils inner IOException");
                }
                String result = new String(outputStream.toByteArray());
                LogUtils.debug("NetRequestUtils result:" + result);
                getUITaskDispatcher().syncDispatch(() -> Toast.show("成功发起get网络请求:" + result));
                HttpResponseCache.getInstalled().flush();
            } catch (IOException e) {
                LogUtils.error("NetRequestUtils IOException");
            }
        });
    }

    private final NetStatusCallback callback = new NetStatusCallback() {
        @Override
        public void onAvailable(NetHandle handle) {
            LogUtils.info("NetStatusCallback onAvailable");
        }

        @Override
        public void onBlockedStatusChanged(NetHandle handle, boolean blocked) {
            LogUtils.info("NetStatusCallback onBlockedStatusChanged");
        }
    };

    public void requestByGet1() {
        String requestUrl = "https://www.baidu.com";
        ThreadPoolUtil.submit(() -> {
        HttpURLConnection connection = null;
        try {
            connection = getHttpURLConnection(requestUrl, "GET");
            connection.connect();
            String response = getReturnString(connection.getInputStream());
            ZSONObject zsonObject = ZSONObject.stringToZSON(response);
            LogUtils.info("NetRequestUtils requestByGet1 :" + zsonObject);
            getUITaskDispatcher().syncDispatch(() -> Toast.show("成功发起get网络请求:" + zsonObject));
        } catch (Exception e) {
            LogUtils.error("NetRequestUtils requestByGet1 :" + e.getMessage());
        }
        });
    }

    public void requestByPost1() {
        ThreadPoolUtil.submit(() -> {
            String requestUrl = "http://10.55.20.48:8082/svnplus/fileSystem/uploadMoel?url=http://120.78.215.13/home/svn/666";
            HttpURLConnection connection = null;
            try {
                connection = getHttpURLConnection(requestUrl, "POST");
                connection.connect();
                String response = getReturnString(connection.getInputStream());
                ZSONObject zsonObject = ZSONObject.stringToZSON(response);
                LogUtils.info("NetRequestUtils requestByPost:" + zsonObject);
                getUITaskDispatcher().syncDispatch(() -> Toast.show("成功发起post网络请求:" + zsonObject));
            } catch (Exception e) {
                LogUtils.error("NetRequestUtilsException requestByPost:" + e.getMessage());
                getUITaskDispatcher().syncDispatch(() -> Toast.show("成功发起post网络请求:" + e.getMessage()));
            }
        });
    }

    public void requestByPost() {
        NetManager netManager = NetManager.getInstance(null);
        if (!netManager.hasDefaultNet()) {
            LogUtils.debug("NetRequestUtils  network is null");
            return;
        }
        ThreadPoolUtil.submit(() -> {
            NetHandle netHandle = netManager.getDefaultNet();
            HttpURLConnection connection = null;
            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                URL url = new URL("http://10.55.20.48:8082/svnplus/fileSystem/uploadMoel?url=http://120.78.215.13/home/svn/666");
                URLConnection urlConnection = netHandle.openConnection(url, java.net.Proxy.NO_PROXY);
                if (urlConnection instanceof HttpURLConnection) {
                    connection = (HttpURLConnection) urlConnection;
                }
                connection.setRequestMethod("POST");
                connection.connect();

                //数据解析
                try (InputStream inputStream = urlConnection.getInputStream()) {
                    byte[] cache = new byte[2 * 1024];
                    int len = inputStream.read(cache);
                    while (len != -1) {
                        outputStream.write(cache, 0, len);
                        len = inputStream.read(cache);
                    }
                } catch (IOException e) {
                    LogUtils.error("NetRequestUtils inner IOException");
                }
                String result = new String(outputStream.toByteArray());
                LogUtils.debug("NetRequestUtils result:" + result);
                getUITaskDispatcher().syncDispatch(() -> Toast.show("成功发起post网络请求:" + result));
            } catch (Exception e) {
                LogUtils.error("NetRequestUtilsException requestByPost:" + e.getMessage());
            }
        });
    }

    /**
     * 请求网络图片
     */
    public void requestNetImage() {
        ThreadPoolUtil.submit(() -> {
            String requestUrl = "https://t7.baidu.com/it/u=4162611394,4275913936&fm=193&f=GIF";
            HttpURLConnection connection = null;
            try {
                connection = getHttpURLConnection(requestUrl, "GET");
                connection.connect();
                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    //将网络请求数据转换成ImageSource
                    ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
                    ImageSource imageSource = ImageSource.create(connection.getInputStream(), srcOpts);
                    //将ImageSource转换成可以设置给image控件的PixelMap对象
                    PixelMap pixelMap = imageSource.createPixelmap(null);
                    getUITaskDispatcher().syncDispatch(() -> image.setPixelMap(pixelMap));
                }
                connection.disconnect();
            } catch (Exception e) {
                LogUtils.error("NetRequestUtilsException  requestNetImage:" + e.getMessage());
            }
        });
    }

    private HttpURLConnection getHttpURLConnection(String requestURL, String requestMethod) throws IOException {
        URL url = new URL(requestURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //设置连接超时时间
        connection.setConnectTimeout(10 * 1000);
        //设置读取服务器数据超时时间
        connection.setReadTimeout(15 * 1000);
        //设置请求方式
        connection.setRequestMethod(requestMethod);
        return connection;
    }

    private String getReturnString(InputStream is) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"));
            StringBuilder sb = new StringBuilder();
            String line = "";

            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            is.close();
            return sb.toString();
        } catch (Exception var5) {
            return null;
        }
    }
}

总结

到此本篇文档就要告一段落了。通过本篇的学习,基本掌握了鸿蒙系统中的网络请求及网络图片加载。
最后跟大家分享一些开发过程中的注意事项

1、鸿蒙系统中默认的网络请求地址格式是https,如果想要访问http网址,需要修改允许明文信息传输的配置

鸿蒙官网关于network配置文档

同样在entry模块的config.json中(如果存在多个module,最好在每一个config.json文件中均添加上该配置)

  "deviceConfig": {
    "default": {
      "network": {
        "cleartextTraffic": true
      }
    }
  },

2、网络请求是耗时操作,必须执行在子线程中,否则报错android.os.NetworkOnMainThreadException

3、在加载网络图片示例中,我们将connection.getInputStream()数据流直接转换成了ImageSource。
但是再请求其他网络地址时,如访问www.baidu.com的返回结果就是html文件,因此在网络连接成功的后续数据处理中,需要注意数据格式。

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-2-25 09:59:24修改
7
收藏 8
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

学习下大佬的敲代码方式

回复
2022-2-25 10:15:25
回复
    相关推荐