彻底解决Android网络请求失败

您所在的位置:网站首页 浙商银行网络请求失败什么原因造成的 彻底解决Android网络请求失败

彻底解决Android网络请求失败

2024-07-09 23:48| 来源: 网络整理| 查看: 265

前言:

不知道大家是否在项目中遇到过请求网络请求失败的情况,事实上在Android 9.0(API 28)后就谷歌就已经禁止明文访问了,以下方法解决可以这个问题。(我这里默认用OkHttp第三方框架来请求网络)

首先我这边自己封装了一个OkHttp封装类,有需要自取,也可以自己分装提高自己的代码编写能力。注:我在get请求失败的时候捕获了异常,这个注意,后面有用到。

public class MyOkHttp { private OkHttpClient okHttpClient; private Gson gson = new Gson(); private volatile static MyOkHttp myOkhttp = null; private MyOkHttp() { okHttpClient = new OkHttpClient .Builder() .hostnameVerifier(new AllowAllHostnameVerifier()) .sslSocketFactory(TrustAllCerts.createSSLSocketFactory(), TrustAllCerts.getX509TrustManager()) .connectTimeout(10, TimeUnit.SECONDS)//连接超时 .readTimeout(500, TimeUnit.SECONDS) .build();//读超时 还有一个写超时 } public static MyOkHttp getInstance() { if (myOkhttp == null) { return newInstance(); } return myOkhttp; } private synchronized static MyOkHttp newInstance() { if (myOkhttp == null) { myOkhttp = new MyOkHttp(); } return myOkhttp; } public void get(String url, final requestMessage requestMessage) { final Request request = new Request.Builder().addHeader("Content-Type", "application/json; charset=utf-8").get().url(url).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { requestMessage.requestFail(); requestMessage.requestComplete(); } @Override public void onResponse(final Call call, Response response) throws IOException { requestMessage.requestComplete(); if (response.isSuccessful()) { requestMessage.requestSuccess(response); } else { requestMessage.requestFail(); LogUtils.e(response.message()); } } }); } public void post(String url, Map param, final requestMessage requestMessage) { FormBody.Builder builder = new FormBody.Builder(); if (param != null) { for (Map.Entry entry : param.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } Request request = new Request.Builder() .post(builder.build()) .url(url) .build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { LogUtils.d(e.toString()); e.printStackTrace(); requestMessage.requestFail(); requestMessage.requestComplete(); } @Override public void onResponse(Call call, Response response) throws IOException { requestMessage.requestComplete(); if (response.isSuccessful()) { requestMessage.requestSuccess(response); } else { requestMessage.requestFail(); LogUtils.d(response.body().string()); } } }); } public void postBitMap(String url, File file, String assetNumber, final requestMessage requestMessage) { MultipartBody.Builder builder = new MultipartBody.Builder() .setType(MultipartBody.FORM); builder.addFormDataPart("picture", "img.jpg", RequestBody.create(MediaType.parse("image/jpg"), file)); builder.addFormDataPart("assetNumber", assetNumber); Request request = new Request.Builder() .url(url) .post(builder.build()) .build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); requestMessage.requestFail(); requestMessage.requestComplete(); } @Override public void onResponse(Call call, Response response) throws IOException { requestMessage.requestComplete(); if (response.isSuccessful()) { requestMessage.requestSuccess(response); } else { requestMessage.requestFail(); LogUtils.d(response.message()); } } }); } //系统时间获取方法 public String getDate() { //获取系统的日期时间 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); return sdf.format(calendar.getTime()); } //系统时间获取方法 public String getTime() { //获取系统的日期时间 Calendar calendar = Calendar.getInstance(); String strDateFormat = "yyyy-MM-dd HH:mm:ss"; SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat, Locale.ENGLISH); return sdf.format(calendar.getTime()); } public Gson getGson() { return gson; } public interface requestMessage { void requestFail(); //失败成功都会回调 void requestComplete(); void requestSuccess(Response response) throws IOException; } } 1.不用http协议,只采用https协议

以下对比两个协议的区别

public class MainActivity extends AppCompatActivity { private static final String TAG = "jiangjianhua"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyOkHttp.getInstance().get("http://www.baidu.com", new MyOkHttp.requestMessage() { @Override public void requestFail() { runOnUiThread(() -> Toast.makeText(MainActivity.this, "连接超时", Toast.LENGTH_SHORT).show()); } @Override public void requestComplete() { } @Override public void requestSuccess(Response response) throws IOException { Log.d(TAG, "response: " + response.body().string()); } }); } }

这个demo就只有一个自动生成的主页面,主页面什么都没有,点击启动。

获得结果:CLEARTEXT communication to www.baidu.com not permitted by network security policy  翻译过来就是   网络安全政策不允许CLEARTEXT与www.baudu.com通信。所以就是网络安全的问题。然后https协议默认带有加密,所以用https协议就不会有问题了。在访问URL那里改成https://www.baidu.com就可以了。看结果:

已经获取到了请求体里面的内容了,就证明请求成功了。

2.加上配置文件  network_security_config.xml

在项目中的res资源文件夹中,创建一个xml文件夹,创建一个文件network_security_config.xml。内容如下:

在 AndroidManifest.xml文件重加入 android:networkSecurityConfig="@xml/network_security_config" 然后把请求的地址协议改回 http

完成,然后启动,结果图:

 最后也访问成功了。

所以,访问不了主要是因为涉及到网络安全,既然是网络安全那我们就尽量遵守这个规则,不关是https还是http都加上就好了。这样就能确保两种协议都能访问成功了。(对了,最后提一嘴,把版本退回Android 9.0之前说不定也可以哦,嘻嘻)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3