Android网络访问相关

文章相关代码链接

Android高版本sdk无法访问http的问题

android sdk27以上无法直接访问http资源,会报错:

java.io.IOException: Cleartext HTTP traffic to x.x.x.x not permitted

解决方法:
1.最简单的处理
AndroidManifest的Application中添加

android:usesCleartextTraffic="true"

2.添加网络安全配置文件
google官方文档:网络安全配置
创建一个xml文件:network_security_config.xml

    
    
        
            example.com
            
                secure.example.com
            
        
    

AndroidManifest的Application中添加

android:networkSecurityConfig="@xml/network_security_config"

使用java的api进行网络访问

这里是使用HttpURLConnection来请求网络数据
项目地址:https://github.com/dolphin845/WebDataTest
实例代码如下:

private void loadData() {
        try {
            URL url = new URL("https://www.sunofbeach.net/content/content/moment/list/1153952789488054272/1");
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(1000);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.connect();
            int responseCode = httpURLConnection.getResponseCode();
            if (responseCode == 200) {
                Map> headerFields = httpURLConnection.getHeaderFields();
                Set>> entries = headerFields.entrySet();
                for (Map.Entry> entry : entries) {
                    Log.d(TAG, entry.getKey() + " == " + entry.getValue());
                }

                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String line = bufferedReader.readLine();
                Gson gson = new Gson();
                GetTextItem getTextItem = gson.fromJson(line, GetTextItem.class);
                updateUI(getTextItem);

                bufferedReader.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

加载大图片避免OOB的问题

理论:第一次读取图片,不写入内存,直接获取到图片的宽高,再通过用户设置的宽高,和这個拉伸形式來计算期望的宽高,结合这四個参数來找出最适合的采样率,或者直接根据屏幕大小,控件大小來计算最佳采样率。

这里主要是通过options的inSampleSize的值来设置采样率

public void loadBigImage(View view) {
        ImageView imageView = this.findViewById(R.id.image_container);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 10;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.test_pic,options);
        imageView.setImageBitmap(bitmap);
    }

上面是写死了采样率,实际项目中需要动态计算采样率,代码如下:

    public void loadBigImage(View view) {
        ImageView imageView = this.findViewById(R.id.image_container);
        BitmapFactory.Options options = new BitmapFactory.Options();
        //If set to true, the decoder will return null (no bitmap)
        //设置为true以后呢,不是真的载入到内存中,只是获取到图片的相关信息
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(),R.mipmap.test_pic,options);
        int width = options.outWidth;
        int height = options.outHeight;
        int measuredWidth = imageView.getMeasuredWidth();
        int measuredHeight = imageView.getMeasuredHeight();
        Log.d(TAG,"width -- > " + width + " measure width -- > " + measuredWidth);
        Log.d(TAG,"height -- > " + height + " measure height -- > " + measuredHeight);
        int sampleSize;
        if(width < measuredWidth || height < measuredHeight) {
            sampleSize = 1;
        } else {
            int scaleX = width / measuredWidth;
            int scaleY = height / measuredHeight;
            sampleSize = scaleX > scaleY ? scaleX : scaleY;
        }
        Log.d(TAG,"sampleSize -- > " + sampleSize);
        options.inSampleSize = sampleSize;
        //If set to true, the decoder will return null (no bitmap)
        //要变成false了,因为真的要载入到内存中了
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.test_pic,options);
        imageView.setImageBitmap(bitmap);
    }

关闭IO流的工具类

相关代码:

public class IOUtils {
    public static void ioClose(Closeable closeable) {
        try {
            closeable.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用OkHttp进行http请求

Okhttp的github项目链接

加载插件方式,在gridle中加入如下代码:

implementation("com.squareup.okhttp3:okhttp:4.3.1")

使用get方式,异步请求网站数据的代码:

getRequestBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //new 一个客户端的实例
                OkHttpClient okHttpClient = new OkHttpClient.Builder()
                        .connectTimeout(10000, TimeUnit.MICROSECONDS)
                        .build();
                //创建一个请求内容
                Request request = new Request.Builder()
                        .get()
                        .url(BASE_URL + "get/text")
                        .build();
                //用client去创建请求任务
                Call task = okHttpClient.newCall(request);
                //异步请求
                task.enqueue(new Callback() {
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {
                        Log.d(TAG, "onFailure == > " + e.getMessage());
                    }
                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        int code = response.code();
                        Log.d(TAG, "code ===> " + code);
                        ResponseBody body = response.body();
                        Log.d(TAG, "body ==> " + body.string());
                    }
                });
            }
        });

使用post提交数据的代码,这里以提交一段json数据举例:

                //new 一个客户端的实例
                OkHttpClient okHttpClient = new OkHttpClient.Builder()
                        .connectTimeout(10000, TimeUnit.MICROSECONDS)
                        .build();

                //要提交的内容
                CommentItem commentItem = new CommentItem("1234567", "this is a comment");
                Gson gson = new Gson();
                String jsonStr = gson.toJson(commentItem);
                MediaType contentType = MediaType.get("application/json");
                RequestBody requestBody = RequestBody.create(jsonStr, contentType);

                Request request = new Request.Builder()
                        .post(requestBody)
                        .url(BASE_URL + "post/comment")
                        .build();

                Call task = okHttpClient.newCall(request);
                task.enqueue(new Callback() {
                    ......
                }

Retrofit进行网络请求

Retrofit是基于OkHttp的二次封装。
文档地址:

retrofit文档

github地址

retrofit API文档

你可能感兴趣的:(Android网络访问相关)