build.gradle
dependencies {
//retrofit + gson + rxjava
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
}
interface ApiService {
@GET("getUserData")
fun getUserData1(): Call
}
fun main1() {
val retrofit = Retrofit.Builder()
.baseUrl("http://mockapi.eolinker.com/9IiwI82f58c23411240ed608ceca204b2f185014507cbe3/")
.build()
val service = retrofit.create(ApiService::class.java)
val call: Call = service.getUserData1()
call.enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val userBean = response.body()?.string()
println("userBean: $userBean")
}
override fun onFailure(call: Call, t: Throwable) {
println("onFailure: $t")
}
})
}
Retrofit 是建立在 OkHttp 之上的一个网络请求封装库,内部依靠 okhttp 来完成实际网络请求。Retrofit 在使用上很简洁, API 通过 interface 来声明。我只需要通过 interface 来声明 API路径、请求方式、请求参数、返回值类型 等各个配置项。
可以看到,getUserData() 方法的请求结果是一个 json 格式的字符串,其返回值类型被定义为 Call , 此处的 ResponseBody 即 okHttp3.ResponseBody ,是 okhttp 提供的对网络请求结果的包装类,Call 即 retrofit2.Call ,是 Retrofit 对 okhttp3.Call 做的一层包装,OkHttp在实际发起请求的时候使用的回调是 okhttp3.Call ,回调内部会中转调用 retrofit2.Call,以便将请求结果转交给外部。
1、converter-gson
API 返回值 Json 转换 :
interface ApiService {
@GET("getUserData")
fun getUserData2(): Call
}
data class UserBean(val status: Int, val msg: String, val data: Data)
data class Data(val userName: String, val userAge: Long)
fun main2() {
val retrofit = Retrofit.Builder()
.baseUrl("http://mockapi.eolinker.com/9IiwI82f58c23411240ed608ceca204b2f185014507cbe3/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(ApiService::class.java)
val call: Call = service.getUserData2()
call.enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val userBean = response.body()
println("userBean: $userBean")
}
override fun onFailure(call: Call, t: Throwable) {
println("onFailure: $t")
}
})
}
2、adapter-rxjava2
adapter-rxjava2 转换返回值为被观察者
interface ApiService {
@GET("getUserData")
fun getUserData3(): Observable
}
data class UserBean(val status: Int, val msg: String, val data: Data)
data class Data(val userName: String, val userAge: Long)
fun main3() {
val retrofit = Retrofit.Builder()
.baseUrl("http://mockapi.eolinker.com/9IiwI82f58c23411240ed608ceca204b2f185014507cbe3/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
val service = retrofit.create(ApiService::class.java)
val call: Observable = service.getUserData3()
call.subscribe({ user ->
println("userBean: $user")
}, { t ->
println("onFailure: $t")
})
}
一、Retrofit请求过程
1、Retrofit.create()
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public T create(final Class service) {
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
2、ServiceMethod
abstract class ServiceMethod {
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
method,
"Method return type must not include a type variable or wildcard: %s",
returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
3、HttpServiceMethod
abstract class HttpServiceMethod extends ServiceMethod {
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
CallAdapter callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(
method,
"'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter>) callAdapter,
continuationBodyNullable);
}
}
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
}
4、OkHttpCall
OkHttpCall 是实际发起 okHttp 请求的地方。当我们调用 fun getUserData(): Call 方法时,返回的 Call 对象实际上是 OkHttp 类型。
final class OkHttpCall implements Call {
private final RequestFactory requestFactory;
private final Object[] args;
private final okhttp3.Call.Factory callFactory;
private final Converter responseConverter;
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;
OkHttpCall(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factory callFactory,
Converter responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
@SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
@Override
public OkHttpCall clone() {
return new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
}
@Override
public synchronized Request request() {
try {
return getRawCall().request();
} catch (IOException e) {
throw new RuntimeException("Unable to create request.", e);
}
}
@Override
public synchronized Timeout timeout() {
try {
return getRawCall().timeout();
} catch (IOException e) {
throw new RuntimeException("Unable to create call.", e);
}
}
/**
* Returns the raw call, initializing it if necessary. Throws if initializing the raw call throws,
* or has thrown in previous attempts to create it.
*/
@GuardedBy("this")
private okhttp3.Call getRawCall() throws IOException {
okhttp3.Call call = rawCall;
if (call != null) return call;
// Re-throw previous failures if this isn't the first attempt.
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
// Create and remember either the success or the failure.
try {
return rawCall = createRawCall();
} catch (RuntimeException | Error | IOException e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
@Override
public void enqueue(final Callback callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
@Override
public synchronized boolean isExecuted() {
return executed;
}
@Override
public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = getRawCall();
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
}
5、RequestFactory
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
private final Method method;
private final HttpUrl baseUrl;
final String httpMethod;
private final @Nullable String relativeUrl;
private final @Nullable Headers headers;
private final @Nullable MediaType contentType;
private final boolean hasBody;
private final boolean isFormEncoded;
private final boolean isMultipart;
private final ParameterHandler[] parameterHandlers;
final boolean isKotlinSuspendFunction;
RequestFactory(Builder builder) {
method = builder.method;
baseUrl = builder.retrofit.baseUrl;
httpMethod = builder.httpMethod;
relativeUrl = builder.relativeUrl;
headers = builder.headers;
contentType = builder.contentType;
hasBody = builder.hasBody;
isFormEncoded = builder.isFormEncoded;
isMultipart = builder.isMultipart;
parameterHandlers = builder.parameterHandlers;
isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
}
okhttp3.Request create(Object[] args) throws IOException {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler[] handlers = (ParameterHandler[]) parameterHandlers;
int argumentCount = args.length;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException(
"Argument count ("
+ argumentCount
+ ") doesn't match expected count ("
+ handlers.length
+ ")");
}
RequestBuilder requestBuilder =
new RequestBuilder(
httpMethod,
baseUrl,
relativeUrl,
headers,
contentType,
hasBody,
isFormEncoded,
isMultipart);
if (isKotlinSuspendFunction) {
// The Continuation is the last parameter and the handlers array contains null at that index.
argumentCount--;
}
List argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
/**
* Inspects the annotations on an interface method to construct a reusable service method. This
* requires potentially-expensive reflection so it is best to build each service method only once
* and reuse it. Builders cannot be reused.
*/
static final class Builder {
// Upper and lower characters, digits, underscores, and hyphens, starting with a character.
private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
boolean gotField;
boolean gotPart;
boolean gotBody;
boolean gotPath;
boolean gotQuery;
boolean gotQueryName;
boolean gotQueryMap;
boolean gotUrl;
@Nullable String httpMethod;
boolean hasBody;
boolean isFormEncoded;
boolean isMultipart;
@Nullable String relativeUrl;
@Nullable Headers headers;
@Nullable MediaType contentType;
@Nullable Set relativeUrlParamNames;
@Nullable ParameterHandler[] parameterHandlers;
boolean isKotlinSuspendFunction;
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError(
method,
"FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
return new RequestFactory(this);
}
}
参考:
https://github.com/leavesCZY/AndroidGuide/blob/master/%E4%B8%BB%E6%B5%81%E5%BC%80%E6%BA%90%E5%BA%93%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%EF%BC%887%EF%BC%89Retrofit%20%E6%BA%90%E7%A0%81%E8%AF%A6%E8%A7%A3.md
你可能感兴趣的:(OkHttp,retrofit,kotlin)
1.如何配置开发环境(JDK、Maven、IDEA)搭建SpringBoot项目
yjx012
java maven intellij-idea spring boot
搭建SpringBoot项目的开发环境主要包括安装和配置JDK、Maven和IDEA(IntelliJIDEA)。以下是详细的步骤和注意事项。1.安装JDK1.1下载JDKDownloadIntelliJIDEA–TheLeadingJavaandKotlinIDE1.2安装JDK下载后,按照安装向导完成安装。安装过程中请记住安装路径,通常为C:\ProgramFiles\Java\jdk-11或
java实现kotlin接口_Kotlin 接口与 Java8 新特性接口详解
天使走自己的路
java实现kotlin接口
前言在看一本关于高性能编程的时候发现Java8中关于接口的新特性的介绍,这个特性是真的棒,解决了一个接口中有多个方法,但并不想实现该接口的类都去实现所有的方法,简单的说就是在类需要的情况再去重写接口。所以有了以下的特性出现。接口增强在Java8的中接口特性中增加以下俩种特性:在接口中可以使用default关键字修饰默认方法或扩展方法,抽象方法因为其特性的原因无法使用接口可以使用static声明为静
Kotlin 优雅的接口实现
GordonH1991
android kotlin java
1.日常遇到的冗余的接口方法实现日常开发中,经常会要实现接口,但是很多场景中,只需要用到其中一两个方法,例如ActivityLifecycleCallbacks,它有很多个接口需要实现,但是很多时候我们只需要用到其中的一两个valmyActivityLifecycleCallbacks=object:Application.ActivityLifecycleCallbacks{/***例如我们只需
Android新版高斯模糊(毛玻璃)官方实现,Kotlin
zhangphil
Android kotlin android kotlin
Android新版高斯模糊(毛玻璃)官方实现,Kotlin从Android12开始,Android官方API支持高斯模糊(毛玻璃)效果。关键是通过RenderEffect实现。https://developer.android.com/reference/android/graphics/RenderEffecthttps://developer.android.com/reference/and
DeepSeekApi对接流式输出异步聊天功能:基于Spring Boot和OkHttp的SSE应用实现
WeiLai1112
DeepSeek Springboot spring boot okhttp 后端 人工智能
实现异步聊天功能:基于SpringBoot和OkHttp的SSE应用在现代Web应用程序开发中,实时更新的能力对于增强用户体验至关重要。本文将详细介绍如何利用SpringBoot框架结合OkHttp库实现一个简单的异步聊天服务,该服务能够接收用户输入并通过Server-SentEvents(SSE)向客户端推送实时更新。一、技术栈选择为了构建这个服务,我们选择了以下技术:SpringBoot:用于
Kotlin:Kotlin类与对象
kkchenjj
工业软件二次开发全集 kotlin 微信 开发语言
Kotlin:Kotlin类与对象Kotlin类的基础1.定义Kotlin类在Kotlin中,定义一个类非常直观。使用class关键字后跟类名,然后在大括号{}中定义类的主体。类可以包含属性、方法、构造函数等。//定义一个简单的Person类classPerson(valname:String,varage
Kotlin 2.1.0 入门教程(十七)接口
xvch
Kotlin kotlin android
接口接口可以包含抽象方法的声明,也可以包含方法的实现。接口与抽象类的不同之处在于,接口无法存储状态。接口可以拥有属性,但这些属性要么必须是抽象的,要么就得提供访问器的实现。接口使用interface关键字来定义:interfaceMyInterface{funbar()funfoo(){//可选函数体。}}实现接口一个类或对象可以实现一个或多个接口:classChild:MyInterface{o
Kotlin 入门教程:基本数据类型
月入鱼饵
Kotlin 入门教程 kotlin 开发语言
本文介绍Kotlin基本数据类型。所有代码均可在Kotlin官方在线代码调试器运行,部分代码下方也会提供链接直达。专栏《零基础入门Kotlin》持续更新中,欢迎订阅!目录1.概览2.数据类型声明2.1显式类型声明2.2.隐式类型声明(类型推理)3.整型4.浮点数5.布尔值(Boolean)6.字符和字符串6.1字符(Char)6.2字符串(String)6.2.1声明6.3.2其它语法部分参考资料
Kotlin 2.1.0 入门教程(十五)继承、重写、派生类初始化顺序
xvch
Kotlin kotlin android
继承所有类都有一个共同的超类Any,对于没有声明超类型的类来说,Any是其默认的超类://隐式继承自Any。classExampleAny有三个方法:equals()、hashCode()和toString()。因此,所有类都定义了这些方法。默认情况下,类是final的,即它们不能被继承。若要使一个类可被继承,需使用open关键字标记它://该类可被继承。openclassBase要声明一个显式的
kotlin中expect和actual关键字修饰的函数作用
闲暇部落
Kotlin kotlin 开发语言 android
在Kotlin多平台编程中,expect和actual关键字用于定义跨平台的抽象和具体实现。这种机制允许开发者声明一个平台无关的接口或函数签名(使用expect),然后在每个目标平台上提供具体的实现(使用actual)。expect关键字expect关键字用于声明一个抽象成员,它可以是类、接口、对象、函数、属性或类型别名。这些声明不包含具体的实现,而是作为跨平台代码中的占位符,表明在某个平台上将提
Kotlin 2.1.0 入门教程(十六)属性、getter、setter、幕后字段、后备属性、编译时常量、延迟初始化
xvch
Kotlin kotlin android
属性声明属性可以使用var关键字声明为可变的,也可以使用val关键字声明为只读的。classAddress{varname:String="Holmes,Sherlock"varstreet:String="Baker"varcity:String="London"varstate:String?=nullvarzip:String="123456"}要使用这些属性,只需通过属性名来引用它们。fu
scala kotlin比较_追随 Kotlin/Scala,看 Java 12-15 的现代语言特性
weixin_39605296
scala kotlin比较 scala list 接受java string
本文原发于我的个人博客:https://hltj.me/java/2020/06/14/java-12-15-lang-features.html。本副本只用于知乎,禁止第三方转载。Java14发布已经过去了三个月,Java15目前也已经到了“RampdownPhaseOne”阶段,其新特性均已敲定。由于12-15都是短期版本,无需考虑也不应该将其用于生产环境。但可以提前了解新特性,以免在下一个L
java 协程 scala_追随 Kotlin/Scala,看 Java 12-15 的现代语言特性
小田linda
java 协程 scala
Java14发布已经过去了三个月,Java15目前也已经到了“RampdownPhaseOne”阶段,其新特性均已敲定。由于12-15都是短期版本,无需考虑也不应该将其用于生产环境。但可以提前了解新特性,以免在下一个LTS(Java17)正式发布时毫无心理准备。Java12-15引入了一系列改进,本文只讨论语言层面的新特性,它们看起来似曾相识——没错,这些特性让人感觉Java在沿Kotlin/Sc
JAVA/RUST/C#/Kotlin 各语言语法糖及特性对比表
zimoyin
java rust c#
各语言语法糖及特性对比表声明:所有数据均由AI整合生成语法糖/特性说明GoC#KotlinJava(版本及备注)Rust局部方法嵌套方法,可访问外部局部变量✅✅✅✅✅(可用闭包,但用fn定义的内嵌函数不能捕获环境)lock语句简化线程同步(Java中对应使用synchronized)❌✅❌(使用synchronized)✅(使用synchronized)❌(采用Mutex+RAII模式实现同步)u
Android Studio 报错:Could not get unknown property ‘kotlin_version‘ for object of type
太难我不会
大数据
导入项目,sync的时候报错:Aproblemoccurredevaluatingproject':app'.>Couldnotgetunknownproperty'kotlin_version'forobjectoftypeorg.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.出现这个问题,我的思路
Android Studio报错:Could not get unknown property ‘kotlin_version‘
zhangphil
Android android
AndroidStudio报错:Couldnotgetunknownproperty'kotlin_version'报错内容:Causedby:groovy.lang.MissingPropertyException:Couldnotgetunknownproperty'kotlin_version'forobjectoftypeorg.gradle.api.internal其中一个解决方案,把:
kotlin标准库里面也有很多java类
yzpyzp
kotlin android java
Kotlin标准库中确实存在许多与Java类直接关联或基于Java类封装的结构,但这并不是“问题”,而是Kotlin与JVM生态深度兼容和互操作性的体现。以下从技术原理和设计哲学的角度详细解释:一、Kotlin与JVM的底层关系Kotlin代码最终会编译成JVM字节码,因此它必须与Java类库无缝协作。Kotlin标准库的设计原则之一就是兼容Java生态,其内部实现会直接或间接依赖Java标准库中
kotlin-kapt
yzpyzp
kotlin android
kotlin-kaptkotlin-kapt是Kotlin的一个插件,专门用于处理注解处理器(AnnotationProcessor)。以下是对该插件的详细解释和指南:kotlin-kapt是什么?kotlin-kapt是Kotlin官方提供的一个插件,用于在Kotlin项目中支持注解处理。KAPT(KotlinAnnotationProcessingTool)是JavaAPT(Annotatio
Android网络技术——HttpUrlConnection和OkHttp
penghc_xhs
Android 第一行代码 android
Android网络技术——HttpUrlConnection和OkHttpHttpURLConnection是一个abstract类,可用于发起网络请求OkHttp不仅在接口封装上做得简单易用,就连在底层实现上也是自成一派,比起原生的HttpURLConnection,可以说是有过之而无不及,现在已经成了广大Android开发者首选的网络通信库一、布局设置注:ScrollView容器用于滚动内部的
Android 访问网络框架之——OkHttp框架的解析
mr丶yang
原创 Okhttp 框架 网络
越来越发现一些第三方的框架比Android原生大的API好用多了,而且android废弃掉了HttpClient,有必要学习一些访问网络的框架,于是踏上了一条框架学习之路,先前学习了Volley框架。今天来解析一下OkHttp框架。一,OkHttp的简单使用,主要包括:一般的get请求一般的post请求基于Http的文件上传文件下载加载图片支持请求回调,直接返回对象、对象集合支持session的保
Android网络框架——OKHttp
闲暇部落
Java android okhttp java
目录一、介绍二、优势三、功能四、应用1.HttpGet的使用步骤2.HttpPost携带参数的使用步骤:3.使用post进行表单(键值对)上传一、介绍OKHttp是一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso)用于替代HttpUrlConnection和ApacheHttpClient(androidAPI236.0里已移除H
Jetpack Compose学习(2)——文本(Text)的使用
l软件定制开发工作室
Android教程 android jetpack
本篇涉及到Kotlin和DSL特性的使用若不了解的话可能会造成代码阅读困难,阅读前确保你有上述基础知识!!!目录基础使用单行文本多样式文本长按可选择可点击文本点击文本跳转链接基础使用@Preview(showBackground=true)@ComposablefuntextDemo(){ComposeDemoTheme{Column(){//基础使用Text(text="Helloworld")
kotlin recycler_view must not be null
yechaoa
Kotlin 疑难杂症 Kotlin recycler_viewm kotlin
报错recycler_viewmustnotbenull解析找不到recycler_view?overridefuninitView(){recycler_view.layoutManager=LinearLayoutManager(mContext)}就上面这一行很简单的代码,居然提示找不到recycler_view,难道是kotlin-android-extensions插件的问题?不可能啊,
kotlin_03: Android-Kotlin 判断网络连接工具类NetWorkUtils
诸葛榆木
kotlin android android-studio kotlin
前言:原文中先是写定义了一个class类,之后使用了我之前博客中提到的companionobject(kotlin中的关键字)把判断网络连接的几个方法做成了类似于java的静态方法即可以使用类名.方法名直接调用。可以直接使用object关键来定义一个类使其变成一个单例类。而且在方法中使用kotlin的?.和?:来简化程序的写法。importandroid.content.Contextimport
Kotlin Android 环境搭建
lsx202406
开发语言
KotlinAndroid环境搭建引言随着移动应用的日益普及,Android开发成为了一个热门的技术领域。Kotlin作为一种现代的编程语言,因其简洁、安全、互操作性强等特点,被越来越多的开发者所喜爱。本文将详细介绍KotlinAndroid环境搭建的步骤,帮助您快速上手KotlinAndroid开发。环境搭建步骤1.安装JDKKotlin是基于JVM的编程语言,因此需要安装Java开发工具包(J
安卓开发用Java、Flutter、Kotlin的区别
陈老师还在写代码
安卓开发 android java flutter
在安卓开发中,Java、Kotlin和Flutter是三种常见的技术选择,各有优缺点。以下是它们的区别:1.Java历史:Java是安卓开发的传统语言,自安卓平台推出以来一直作为主要开发语言。成熟度:拥有丰富的库和工具,社区支持广泛。性能:性能良好,但不如Kotlin简洁。开发效率:代码冗长,开发效率较低。学习曲线:相对容易上手,适合初学者。2.Kotlin历史:Kotlin由JetBrains开
Kotlin实战经验:将接口回调转换成suspend挂起函数
折翅鵬
Kotlin kotlin
在Kotlin协程中,suspendCoroutine和suspendCancellableCoroutine是用于将回调或基于future的异步操作转换成挂起函数。suspendCoroutine用途:将回调式异步操作转换为可挂起函数行为:启动一个新的协程来处理基于回调的操作挂起当前协程,直到调用回调回调负责使用结果或异常恢复协程取消:需要在回调或启动的协程中手动取消逻辑,从而正确清理资源sus
Java 的 OkHttp 高级进阶:HTTP 请求的艺术
墨瑾轩
一起学学Java【一】 java okhttp http
关注墨瑾轩,带你探索编程的奥秘!超萌技术攻略,轻松晋级编程高手技术宝库已备好,就等你来挖掘订阅墨瑾轩,智趣学习不孤单即刻启航,编程之旅更有趣嘿,小伙伴们!今天我们要一起探索OkHttp的高级特性,这是一个非常棒的JavaHTTP客户端库,它可以帮助我们轻松地发送HTTP请求并接收响应。无论你是刚刚接触OkHttp,还是想要更上一层楼,这篇指南都将为你提供宝贵的指导。让我们一起揭开它的神秘面纱吧!O
Android-Framework:Binder全解析(二,kotlin静态方法
m0_66155658
程序员 架构 移动开发 android
是通过ServiceManagerNative.asInterface()方法来获取ServiceManager对象,asInterface方法的参数中是调用了BinderInternal.getContextObject()方法。这是一个native方法。getContextObject()staticjobjectandroid_os_BinderInternal_getContextObje
kotlin作用域函数run、let、apply、with、also的区别和使用
Android_阿拉拉
kotlin kotlin android 作用域函数
在Kotlin中,run、let、apply、with、also这几个方法有一些区别,主要体现在用途和使用方式上。一、run方法函数签名:T.run(block:T.()->R),这里的T是接收者类型,R是返回值类型。它接收一个lambda表达式作为参数,在lambda表达式中可以访问接收者对象,并返回一个结果。用途:可以在需要对一个对象进行一系列操作并返回一个结果时使用。常用于减少临时变量的使用
继之前的线程循环加到窗口中运行
3213213333332132
java thread JFrame JPanel
之前写了有关java线程的循环执行和结束,因为想制作成exe文件,想把执行的效果加到窗口上,所以就结合了JFrame和JPanel写了这个程序,这里直接贴出代码,在窗口上运行的效果下面有附图。
package thread;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util
linux 常用命令
BlueSkator
linux 命令
1.grep
相信这个命令可以说是大家最常用的命令之一了。尤其是查询生产环境的日志,这个命令绝对是必不可少的。
但之前总是习惯于使用 (grep -n 关键字 文件名 )查出关键字以及该关键字所在的行数,然后再用 (sed -n '100,200p' 文件名),去查出该关键字之后的日志内容。
但其实还有更简便的办法,就是用(grep -B n、-A n、-C n 关键
php heredoc原文档和nowdoc语法
dcj3sjt126com
PHP heredoc nowdoc
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Current To-Do List</title>
</head>
<body>
<?
overflow的属性
周华华
JavaScript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml&q
《我所了解的Java》——总体目录
g21121
java
准备用一年左右时间写一个系列的文章《我所了解的Java》,目录及内容会不断完善及调整。
在编写相关内容时难免出现笔误、代码无法执行、名词理解错误等,请大家及时指出,我会第一时间更正。
&n
[简单]docx4j常用方法小结
53873039oycg
docx
本代码基于docx4j-3.2.0,在office word 2007上测试通过。代码如下:
import java.io.File;
import java.io.FileInputStream;
import ja
Spring配置学习
云端月影
spring配置
首先来看一个标准的Spring配置文件 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi=&q
Java新手入门的30个基本概念三
aijuans
java 新手 java 入门
17.Java中的每一个类都是从Object类扩展而来的。 18.object类中的equal和toString方法。 equal用于测试一个对象是否同另一个对象相等。 toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.(toString 方法是一个很重要的方法) 19.通用编程:任何类类型的所有值都可以同object类性的变量来代替。
《2008 IBM Rational 软件开发高峰论坛会议》小记
antonyup_2006
软件测试 敏捷开发 项目管理 IBM 活动
我一直想写些总结,用于交流和备忘,然都没提笔,今以一篇参加活动的感受小记开个头,呵呵!
其实参加《2008 IBM Rational 软件开发高峰论坛会议》是9月4号,那天刚好调休.但接着项目颇为忙,所以今天在中秋佳节的假期里整理了下.
参加这次活动是一个朋友给的一个邀请书,才知道有这样的一个活动,虽然现在项目暂时没用到IBM的解决方案,但觉的参与这样一个活动可以拓宽下视野和相关知识.
PL/SQL的过程编程,异常,声明变量,PL/SQL块
百合不是茶
PL/SQL的过程编程 异常 PL/SQL块 声明变量
PL/SQL;
过程;
符号;
变量;
PL/SQL块;
输出;
异常;
PL/SQL 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言PL/SQL 是对 SQL 的扩展,sql的执行时每次都要写操作
Mockito(三)--完整功能介绍
bijian1013
持续集成 mockito 单元测试
mockito官网:http://code.google.com/p/mockito/,打开documentation可以看到官方最新的文档资料。
一.使用mockito验证行为
//首先要import Mockito
import static org.mockito.Mockito.*;
//mo
精通Oracle10编程SQL(8)使用复合数据类型
bijian1013
oracle 数据库 plsql
/*
*使用复合数据类型
*/
--PL/SQL记录
--定义PL/SQL记录
--自定义PL/SQL记录
DECLARE
TYPE emp_record_type IS RECORD(
name emp.ename%TYPE,
salary emp.sal%TYPE,
dno emp.deptno%TYPE
);
emp_
【Linux常用命令一】grep命令
bit1129
Linux常用命令
grep命令格式
grep [option] pattern [file-list]
grep命令用于在指定的文件(一个或者多个,file-list)中查找包含模式串(pattern)的行,[option]用于控制grep命令的查找方式。
pattern可以是普通字符串,也可以是正则表达式,当查找的字符串包含正则表达式字符或者特
mybatis3入门学习笔记
白糖_
sql ibatis qq jdbc 配置管理
MyBatis 的前身就是iBatis,是一个数据持久层(ORM)框架。 MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis对JDBC进行了一次很浅的封装。
以前也学过iBatis,因为MyBatis是iBatis的升级版本,最初以为改动应该不大,实际结果是MyBatis对配置文件进行了一些大的改动,使整个框架更加方便人性化。
Linux 命令神器:lsof 入门
ronin47
lsof
lsof是系统管理/安全的尤伯工具。我大多数时候用它来从系统获得与网络连接相关的信息,但那只是这个强大而又鲜为人知的应用的第一步。将这个工具称之为lsof真实名副其实,因为它是指“列出打开文件(lists openfiles)”。而有一点要切记,在Unix中一切(包括网络套接口)都是文件。
有趣的是,lsof也是有着最多
java实现两个大数相加,可能存在溢出。
bylijinnan
java实现
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BigIntegerAddition {
/**
* 题目:java实现两个大数相加,可能存在溢出。
* 如123456789 + 987654321
Kettle学习资料分享,附大神用Kettle的一套流程完成对整个数据库迁移方法
Kai_Ge
Kettle
Kettle学习资料分享
Kettle 3.2 使用说明书
目录
概述..........................................................................................................................................7
1.Kettle 资源库管
[货币与金融]钢之炼金术士
comsci
金融
自古以来,都有一些人在从事炼金术的工作.........但是很少有成功的
那么随着人类在理论物理和工程物理上面取得的一些突破性进展......
炼金术这个古老
Toast原来也可以多样化
dai_lm
android toast
Style 1: 默认
Toast def = Toast.makeText(this, "default", Toast.LENGTH_SHORT);
def.show();
Style 2: 顶部显示
Toast top = Toast.makeText(this, "top", Toast.LENGTH_SHORT);
t
java数据计算的几种解决方法3
datamachine
java hadoop ibatis r-langue r
4、iBatis
简单敏捷因此强大的数据计算层。和Hibernate不同,它鼓励写SQL,所以学习成本最低。同时它用最小的代价实现了计算脚本和JAVA代码的解耦,只用20%的代价就实现了hibernate 80%的功能,没实现的20%是计算脚本和数据库的解耦。
复杂计算环境是它的弱项,比如:分布式计算、复杂计算、非数据
向网页中插入透明Flash的方法和技巧
dcj3sjt126com
html Web Flash
将
Flash 作品插入网页的时候,我们有时候会需要将它设为透明,有时候我们需要在Flash的背面插入一些漂亮的图片,搭配出漂亮的效果……下面我们介绍一些将Flash插入网页中的一些透明的设置技巧。
一、Swf透明、无坐标控制 首先教大家最简单的插入Flash的代码,透明,无坐标控制: 注意wmode="transparent"是控制Flash是否透明
ios UICollectionView的使用
dcj3sjt126com
UICollectionView的使用有两种方法,一种是继承UICollectionViewController,这个Controller会自带一个UICollectionView;另外一种是作为一个视图放在普通的UIViewController里面。
个人更喜欢第二种。下面采用第二种方式简单介绍一下UICollectionView的使用。
1.UIViewController实现委托,代码如
Eos平台java公共逻辑
蕃薯耀
Eos平台java公共逻辑 Eos平台 java公共逻辑
Eos平台java公共逻辑
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
蕃薯耀 2015年6月1日 17:20:4
SpringMVC4零配置--Web上下文配置【MvcConfig】
hanqunfeng
springmvc4
与SpringSecurity的配置类似,spring同样为我们提供了一个实现类WebMvcConfigurationSupport和一个注解@EnableWebMvc以帮助我们减少bean的声明。
applicationContext-MvcConfig.xml
<!-- 启用注解,并定义组件查找规则 ,mvc层只负责扫描@Controller -->
<
解决ie和其他浏览器poi下载excel文件名乱码
jackyrong
Excel
使用poi,做传统的excel导出,然后想在浏览器中,让用户选择另存为,保存用户下载的xls文件,这个时候,可能的是在ie下出现乱码(ie,9,10,11),但在firefox,chrome下没乱码,
因此必须综合判断,编写一个工具类:
/**
*
* @Title: pro
挥洒泪水的青春
lampcy
编程 生活 程序员
2015年2月28日,我辞职了,离开了相处一年的触控,转过身--挥洒掉泪水,毅然来到了兄弟连,背负着许多的不解、质疑——”你一个零基础、脑子又不聪明的人,还敢跨行业,选择Unity3D?“,”真是不自量力••••••“,”真是初生牛犊不怕虎•••••“,••••••我只是淡淡一笑,拎着行李----坐上了通向挥洒泪水的青春之地——兄弟连!
这就是我青春的分割线,不后悔,只会去用泪水浇灌——已经来到
稳增长之中国股市两点意见-----严控做空,建立涨跌停版停牌重组机制
nannan408
对于股市,我们国家的监管还是有点拼的,但始终拼不过飞流直下的恐慌,为什么呢?
笔者首先支持股市的监管。对于股市越管越荡的现象,笔者认为首先是做空力量超过了股市自身的升力,并且对于跌停停牌重组的快速反应还没建立好,上市公司对于股价下跌没有很好的利好支撑。
我们来看美国和香港是怎么应对股灾的。美国是靠禁止重要股票做空,在
动态设置iframe高度(iframe高度自适应)
Rainbow702
JavaScript iframe contentDocument 高度自适应 局部刷新
如果需要对画面中的部分区域作局部刷新,大家可能都会想到使用ajax。
但有些情况下,须使用在页面中嵌入一个iframe来作局部刷新。
对于使用iframe的情况,发现有一个问题,就是iframe中的页面的高度可能会很高,但是外面页面并不会被iframe内部页面给撑开,如下面的结构:
<div id="content">
<div id=&quo
用Rapael做图表
tntxia
rap
function drawReport(paper,attr,data){
var width = attr.width;
var height = attr.height;
var max = 0;
&nbs
HTML5 bootstrap2网页兼容(支持IE10以下)
xiaoluode
html5 bootstrap
<!DOCTYPE html>
<html>
<head lang="zh-CN">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">