在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:yanzhenjie/NoHttp开源软件地址:https://github.com/yanzhenjie/NoHttp开源编程语言:Java 100.0%开源软件介绍:NoHttpQQ技术交流群:46505645 特别说明:强烈建议开发者切换到另一个网络框架Kalle,Kalle在架构设计上、Api设计上、功能实现上都更加健壮和完善,文档也比较全面。 Kalle开源地址:https://github.com/yanzhenjie/Kalle NoHttp依旧正常维护,正在使用和即将要使用的同学可以放心使用。 添加依赖如果使用HttpURLConnection作为网络层 implementation 'com.yanzhenjie.nohttp:nohttp:1.1.11' 如果要使用OkHttp作为网络层,请再依赖 implementation 'com.yanzhenjie.nohttp:okhttp:1.1.11' 一般初始化直接初始化后,一切采用默认设置。 NoHttp.initialize(this); 高级初始化InitializationConfig config = InitializationConfig.newBuilder(context)
// 其它配置。
...
.build();
NoHttp.initialize(config); 关于超时,很多人都没有彻底理解或理解有误差,本人在知乎上写过一个答案,请参考: 下面介绍上方省略的其它配置的详情。 InitializationConfig config = InitializationConfig.newBuilder(context)
// 全局连接服务器超时时间,单位毫秒,默认10s。
.connectionTimeout(30 * 1000)
// 全局等待服务器响应超时时间,单位毫秒,默认10s。
.readTimeout(30 * 1000)
// 配置缓存,默认保存数据库DBCacheStore,保存到SD卡使用DiskCacheStore。
.cacheStore(
// 如果不使用缓存,setEnable(false)禁用。
new DBCacheStore(context).setEnable(true)
)
// 配置Cookie,默认保存数据库DBCookieStore,开发者可以自己实现CookieStore接口。
.cookieStore(
// 如果不维护cookie,setEnable(false)禁用。
new DBCookieStore(context).setEnable(true)
)
// 配置网络层,默认URLConnectionNetworkExecutor,如果想用OkHttp:OkHttpNetworkExecutor。
.networkExecutor()
// 全局通用Header,add是添加,多次调用add不会覆盖上次add。
.addHeader()
// 全局通用Param,add是添加,多次调用add不会覆盖上次add。
.addParam()
.sslSocketFactory() // 全局SSLSocketFactory。
.hostnameVerifier() // 全局HostnameVerifier。
.retry(x) // 全局重试次数,配置后每个请求失败都会重试x次。
.build(); 说明:
配置缓存位置为SD卡示例: InitializationConfig config = InitializationConfig.newBuilder(context)
.cacheStore(
new DiskCacheStore(context) // 保存在context.getCahceDir()文件夹中。
// new DiskCacheStore(path) // 保存在path文件夹中,path是开发者指定的绝对路径。
)
.build(); 添加全局请求头、参数示例: InitializationConfig config = InitializationConfig.newBuilder(context)
.addHeader("Token", "123") // 全局请求头。
.addHeader("Token", "456") // 全局请求头,不会覆盖上面的。
.addParam("AppVersion", "1.0.0") // 全局请求参数。
.addParam("AppType", "Android") // 全局请求参数。
.addParam("AppType", "iOS") // 全局请求参数,不会覆盖上面的两个。
.build(); 需要的权限<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 调试模式Logger.setDebug(true);// 开启NoHttp的调试模式, 配置后可看到请求过程、日志和错误信息。
Logger.setTag("NoHttpSample");// 打印Log的tag。 开启NoHttp的调试模式后可看到请求过程、日志和错误信息,基本不用抓包。可以看到请求头、请求数据、响应头、Cookie等,而且打印出的Log非常整齐。 所以说,如果开发者使用过程中遇到什么问题了,开启调试模式,一切妖魔鬼怪都会现形的。 第三方异步框架
下面是两个项目群里的基友基于RxJava + NoHttp封装的,开发者可以作为参考或者直接使用:
同步请求和异步请求
同步请求一个请求 StringRequest req = new String("http://api.nohttp.net", RequestMethod.POST);
Response<String> response = SyncRequestExecutor.INSTANCE.execute(req);
if (response.isSucceed()) {
// 请求成功。
} else {
// 请求失败,拿到错误:
Exception e = response.getException();
} 当然同步请求只适合在子线程中使用,因为Android主线程不允许发起网络请求。当然如果使用 异步请求-AsyncRequestExecutorStringRequest request = new StringRequest("http://api.nohttp.net");
Cancelable cancel = AsyncRequestExecutor.INSTANCE.execute(0, request, new SimpleResponseListener<String>() {
@Override
public void onSucceed(int what, Response<String> response) {
// 请求成功。
}
@Override
public void onFailed(int what, Response<String> response) {
// 请求失败。
}
});
// 如果想取消请求:
cancel.cancel();
// 判断是否取消:
boolean isCancelled = cancel.isCancelled(); 这种方式是基于线程池的,它没有队列的优先级的特点了。 异步请求-RequestQueueRequestQueue queue = NoHttp.newRequestQueue(); // 默认三个并发,此处可以传入并发数量。
...
// 发起请求:
queue.add(what, request, listener);
...
// 使用完后需要关闭队列释放CPU:
queue.stop(); 也可以自己建立队列: // 也可以自己建立队列:
RequestQueue queue = new RequestQueue(5);
queue.start(); // 开始队列。
...
// 发起请求:
queue.add(what, request, listener);
...
// 使用完后需要关闭队列:
queue.stop(); 很多同学有一个习惯就是每发起一个请求就new一个队列,这是绝对错误的用法,例如某同学封装的一个方法: public <T> void request(Request<T> request, SampleResponseListener<T> listener) {
RequestQueue queue = NoHttp.newRequestQueue(5);
queue.add(0, request, listener);
} 再次声明一下,上面的这段用法是错误的。 对于想直接调用队列就能请求的开发者, // 比如请求队列单例模式:
NoHttp.getRequestQueueInstance().add...
...
// 比如下载队列单例模式:
NoHttp.getDownloadQueueInstance().add... 当然开发者可以直接使用上面讲到的异步请求执行器: 队列的正确用法队列正确的用法有两种,一种是每一个页面使用一个队列,在页面退出时调用 用法一,开发者可以写一个 public class BaseActivity extends Activity {
private RequestQueue queue;
@Override
public void onCreate(Bundle savedInstanceState) {
queue = NoHttp.newRequestQueue();
}
// 提供给子类请求使用。
public <T> void request(int what, Request<T> request, SimpleResponseListener<T> listener) {
queue.add(what, request, listener);
}
@Override
public void onDestory() {
queue.stop();
}
} 用法二,使用单例模式封装一个全局专门负责请求的类,使全局仅仅保持一个 StringRequest request = new StringRequest("http://api.nohttp.net", RequestMethod.POST);
CallServer.getInstance().request(0, request, listener); 上面的 public class CallServer {
private static CallServer instance;
public static CallServer getInstance() {
if (instance == null)
synchronized (CallServer.class) {
if (instance == null)
instance = new CallServer();
}
return instance;
}
private RequestQueue queue;
private CallServer() {
queue = NoHttp.newRequestQueue(5);
}
public <T> void request(int what, Request<T> request, SimpleResponseListener<T> listener) {
queue.add(what, request, listener);
}
// 完全退出app时,调用这个方法释放CPU。
public void stop() {
queue.stop();
}
} 注意:上面的出现的
其它特点和用法下面将会介绍
所以本人写了一片如何结合业务直接请求 请求不同数据的几种Request
// 请求String:
StringRequest request = new StringRequest(url, method);
// 请求Bitmap:
ImageRequest request = new ImageRequest(url, method);
// 请求JSONObject:
JsonObjectRequest request = new JsonObjectRequest(url, method);
// 请求JSONArray:
JsonArrayRequest request = new JsonArrayRequest(url, method); 拼装URL这个能力是在1.1.3开始增加的,也是本次升级的一个亮点,增加拼装URL的方法,比如服务器是RESTFUL风格的API,请求用户信息时可能是这样一个URL:
这里的
现在可以这样做:
也就是说开发者可以动态拼装URL了。 添加请求头请求头支持添加各种类型,比如 StringRequest request = new StringRequest(url, RequestMethod.POST);
.addHeader("name", "yanzhenjie") // String类型。
.addHeader("age", "18") // int类型。
.setHeader("sex", "男") // setHeader将会覆盖已经存在的key。
... 添加参数请求头支持添加各种类型,比如 StringRequest request = new StringRequest(url, RequestMethod.POST);
.add("name", "严振杰") // String类型
.add("age", 18) // int类型
.add("age", "20") // add方法不会覆盖已经存在key,所以age将会有两个值:18, 20。
.set("sex", "女") // set会覆盖已存在的key。
.set("sex", "男") // 比如最终sex就只有一个值:男。
// 添加File
.add("head", file)
.add("head", new FileBinary(file))
// 添加Bitmap
.add("head", new BitmapBinary(bitmap))
// 添加ByteArray
.add("head", new ByteArrayBinary(byte[]))
// 添加InputStream
.add("head", new InputStreamBinary(inputStream)); 另外需要说明原来的 String、File、Binary、List<String>、List<Binary>、List<File>、List<Object> 代码举例说明: Map<String, Object> params = new HashMap<>();
params.put("name", "yanzhenjie");
params.put("head", new File(path));
params.put("logo", new FileBinary(file));
params.put("age", 18);
params.put("height", 180.5);
List<String> hobbies = new ArrayList<>();
hobbies.add("篮球");
hobbies.add("帅哥");
params.put("hobbies", hobbies);
List<File> goods = new ArrayList<>();
goods.add(file1);
goods.add(file2);
params.put("goods", goods);
List<Object> otherParams = new ArrayList<>();
otherParams.add("yanzhenjie");
otherParams.add(1);
otherParams.add(file);
otherParams.add(new FileBinary(file));
params.put("other", otherParams); 当然,真实开发中第三种和文件一起使用同一个 文件上传有两种形式,第一种:以表单的形式上传,第二种:以
StringRequest request = ...
request.add("file", new FileBinary(file));
StringRequest request = ...
request.add("file1", new FileBinary(File));
request.add("file2", new FileBinary(File));
request.add("file3", new InputStreamBinary(InputStream));
request.add("file4", new ByteArrayBinary(byte[]));
request.add("file5", new BitmapBinary(Bitmap));
StringRequest request = ...
fileList.add("image", new FileBinary(File));
fileList.add("image", new InputStreamBinary(InputStream));
fileList.add("image", new ByteArrayBinary(byte[]));
fileList.add("image", new BitmapBinary(Bitmap)); 或者: StringRequest request = ...;
List<Binary> fileList = ...;
fileList.add(new FileBinary(File));
fileList.add(new InputStreamBinary(InputStream));
fileList.add(new ByteArrayBinary(byte[]));
fileList.add(new BitmapStreamBinary(Bitmap));
request.add("file_list", fileList); 第二种 提交请求包体提交Body分为提交 具体用法如下: // 提交普通String
request.setDefineRequestBody(String, ContentType);
// 提交json字符串
request.setDefineRequestBodyForJson(< |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论