文章相关代码链接
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文档