Android 将保存一个改装实例的单例
因此,我创建了一个登录名,该登录名将接受用户输入的用户名和密码,并使用Android 将保存一个改装实例的单例,android,kotlin,singleton,retrofit,okhttp3,Android,Kotlin,Singleton,Retrofit,Okhttp3,因此,我创建了一个登录名,该登录名将接受用户输入的用户名和密码,并使用Base64对其进行编码,以便创建一个令牌,格式为:(“Authorization”,AUTH),其中AUTH=“Basic”+Base64编码。这是通过标题发送的 最后,它看起来是这样的:Authorization:Basic XXXXXX,其中XXXXXX是用户令牌 然后,它将通过API请求检查数据库中是否存在该用户 我正在使用reformation和OkHttp3与reformationclient在同一类中,该类负责使
Base64
对其进行编码,以便创建一个令牌,格式为:(“Authorization”,AUTH)
,其中AUTH=“Basic”+Base64编码
。这是通过标题发送的
最后,它看起来是这样的:Authorization:Basic XXXXXX
,其中XXXXXX
是用户令牌
然后,它将通过API请求检查数据库中是否存在该用户
我正在使用reformation
和OkHttp3
与reformationclient
在同一类中,该类负责使用API并添加这些标题
稍后,我将在登录活动中使用client
类
我现在需要做的是,通过创建一个Singleton
,在成功登录后存储改型的数据,使这个“令牌”可用于所有其他活动。但我不知道怎么做
我三周前开始学习Kotlin和Android
这是我的密码:
GET_LOGIN.kt
interface GET_LOGIN {
@GET("login")
fun getAccessToken() : Call<String>
}
class RetrofitClient {
fun login(username:String, password:String){
val credentials = username + ":" + password
val AUTH = "Basic " + Base64.encodeToString(credentials.toByteArray(Charsets.UTF_8), Base64.DEFAULT).trim()
retrofit = init(AUTH)
}
// Initializing Retrofit
fun init(AUTH: String) : Retrofit{
// Creating the instance of an Interceptor
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
// Creating the OkHttp Builder
val client = OkHttpClient().newBuilder()
// Creating the custom Interceptor with Headers
val interceptor = Interceptor { chain ->
val request = chain?.request()?.newBuilder()?.addHeader("Authorization", AUTH)?.build()
chain?.proceed(request)
}
client.addInterceptor(interceptor) // Attaching the Interceptor
//client.addInterceptor(logging) // Attaching the Interceptor
// Creating the instance of a Builder
val retrofit = Retrofit.Builder()
.baseUrl("https://srodki.herokuapp.com/") // The API server
.client(client.build()) // Adding Http Client
.addConverterFactory(GsonConverterFactory.create()) // Object Converter
.build()
return retrofit
}
lateinit var retrofit : Retrofit
fun providesGetLogin(): GET_LOGIN = retrofit.create(GET_LOGIN::class.java)
}
var RetrofitClient : RetrofitClient = RetrofitClient()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
loginBtn.setOnClickListener {
val user = userTxt.text.toString()
val pass = passTxt.text.toString()
if (validateLogin(user, pass)){
login(user, pass)
}
}
}
fun validateLogin(user: String, pass: String): Boolean {
if (user == null || user.trim().isEmpty()){
Toast.makeText(this, "Missing Username or Password", Toast.LENGTH_SHORT).show()
return false
}
if (pass == null || pass.trim().isEmpty()){
Toast.makeText(this, "Missing Username or Password", Toast.LENGTH_SHORT).show()
return false
}
return true
}
fun login(user: String, pass: String) {
RetrofitClient.login(user, pass)
val apiLogin = RetrofitClient.providesGetLogin().getAccessToken()
apiLogin.enqueue(object : Callback<LoginResponse> {
override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
if(response.isSuccessful){
if(response.body()?.code == 0){
Toast.makeText(this@LoginActivity, "Login Successful!", Toast.LENGTH_SHORT).show()
val intent = Intent(this@LoginActivity, List_usersActivity::class.java)
startActivity(intent)
} else {
Toast.makeText(this@LoginActivity, "Login Failed.", Toast.LENGTH_SHORT).show()
}
}
}
override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
Toast.makeText(this@LoginActivity, "Login Failed.", Toast.LENGTH_SHORT).show()
}
})
}
}
LoginActivity.kt
interface GET_LOGIN {
@GET("login")
fun getAccessToken() : Call<String>
}
class RetrofitClient {
fun login(username:String, password:String){
val credentials = username + ":" + password
val AUTH = "Basic " + Base64.encodeToString(credentials.toByteArray(Charsets.UTF_8), Base64.DEFAULT).trim()
retrofit = init(AUTH)
}
// Initializing Retrofit
fun init(AUTH: String) : Retrofit{
// Creating the instance of an Interceptor
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
// Creating the OkHttp Builder
val client = OkHttpClient().newBuilder()
// Creating the custom Interceptor with Headers
val interceptor = Interceptor { chain ->
val request = chain?.request()?.newBuilder()?.addHeader("Authorization", AUTH)?.build()
chain?.proceed(request)
}
client.addInterceptor(interceptor) // Attaching the Interceptor
//client.addInterceptor(logging) // Attaching the Interceptor
// Creating the instance of a Builder
val retrofit = Retrofit.Builder()
.baseUrl("https://srodki.herokuapp.com/") // The API server
.client(client.build()) // Adding Http Client
.addConverterFactory(GsonConverterFactory.create()) // Object Converter
.build()
return retrofit
}
lateinit var retrofit : Retrofit
fun providesGetLogin(): GET_LOGIN = retrofit.create(GET_LOGIN::class.java)
}
var RetrofitClient : RetrofitClient = RetrofitClient()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
loginBtn.setOnClickListener {
val user = userTxt.text.toString()
val pass = passTxt.text.toString()
if (validateLogin(user, pass)){
login(user, pass)
}
}
}
fun validateLogin(user: String, pass: String): Boolean {
if (user == null || user.trim().isEmpty()){
Toast.makeText(this, "Missing Username or Password", Toast.LENGTH_SHORT).show()
return false
}
if (pass == null || pass.trim().isEmpty()){
Toast.makeText(this, "Missing Username or Password", Toast.LENGTH_SHORT).show()
return false
}
return true
}
fun login(user: String, pass: String) {
RetrofitClient.login(user, pass)
val apiLogin = RetrofitClient.providesGetLogin().getAccessToken()
apiLogin.enqueue(object : Callback<LoginResponse> {
override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
if(response.isSuccessful){
if(response.body()?.code == 0){
Toast.makeText(this@LoginActivity, "Login Successful!", Toast.LENGTH_SHORT).show()
val intent = Intent(this@LoginActivity, List_usersActivity::class.java)
startActivity(intent)
} else {
Toast.makeText(this@LoginActivity, "Login Failed.", Toast.LENGTH_SHORT).show()
}
}
}
override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
Toast.makeText(this@LoginActivity, "Login Failed.", Toast.LENGTH_SHORT).show()
}
})
}
}
var-reformationclient:reformationclient=reformationclient()
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity\u登录)
loginBtn.setOnClickListener{
val user=userTxt.text.toString()
val pass=passTxt.text.toString()
if(验证登录(用户,通过)){
登录(用户,通行证)
}
}
}
fun validateLogin(用户:字符串,传递:字符串):布尔值{
if(user==null | | user.trim().isEmpty()){
Toast.makeText(这是“缺少用户名或密码”,Toast.LENGTH\u SHORT.show())
返回错误
}
if(pass==null | | pass.trim().isEmpty()){
Toast.makeText(这是“缺少用户名或密码”,Toast.LENGTH\u SHORT.show())
返回错误
}
返回真值
}
有趣的登录(用户:字符串,密码:字符串){
登录(用户,通过)
val apiLogin=client.providesGetLogin().getAccessToken()
排队(对象:回调{
覆盖fun onResponse(调用:调用,响应:响应){
if(response.issucessful){
if(response.body()?.code==0){
Toast.makeText(this@LoginActivity,“登录成功!”,Toast.LENGTH\u SHORT.show()
val intent=intent(this@LoginActivity,List_usersActivity::class.java)
星触觉(意图)
}否则{
Toast.makeText(this@LoginActivity,“登录失败”,Toast.LENGTH\u SHORT.show()
}
}
}
覆盖失效时的乐趣(调用:调用,t:可丢弃){
Toast.makeText(this@LoginActivity,“登录失败”,Toast.LENGTH\u SHORT.show()
}
})
}
}
首先,请在java和kotlin上使用camel case。我们有java和kotlin的编程标准。我可以看出您正在尝试进行DI,但在Android中并非如此。
无论如何,您可以通过几种方法来实现这一点,甚至不用使用单例,而是将其保存在存储上。选项包括共享首选项、本地存储和SQLite。但是,如果您坚持使用单例。您可以这样做:
object MySingleton { // This is how you declare singletons in kotlin
lateinit var token: String;
}
编辑
因此,从您的评论来看,您似乎需要存储令牌。您可以从使用SharedReferences(数据库会更好)开始,并将令牌存储在那里。我想你不知道怎么做,下面是一个例子:
val sp = SharedPreferences("sp", 0);
sp.edit().putString("token", theTokenVariable); // not sure of this function
sp.edit().apply(); // you could use commit if you dont mind sharedpreferences to lag your screen(if it ever will)
现在,您如何从改装中获得代币?我现在唯一能帮助您的方法是,您可以从改装调用的onResponse接收的响应变量中检索响应主体。从这里开始,这就是你的问题,伙计。我不知道您的响应是如何格式化的,应该如何检索等。建议将其格式化为JSON。是的,但您将如何应用于这种情况?我已经知道Kotlin是如何创建单身的。我不明白你的意思。如果您知道单例是如何工作的,那么您还不了解什么?如何在成功登录后存储客户端的数据,并在将来的类中使用它。我需要上新课吗?我是否在client
类中使用伴生对象?我该如何编码这是个问题。还有一些参数。