本文将分享android-Kotlin类型不匹配编译错误:要求成功,发现MyError的详细内容,并且还将对kotlinunresolvedreference进行详尽解释,此外,我们还将为大家带来关于
本文将分享android-Kotlin类型不匹配编译错误:要求成功,发现MyError的详细内容,并且还将对kotlin unresolved reference进行详尽解释,此外,我们还将为大家带来关于Android & Kotlin:基于Room、Kotlin协程的MVVM app、android -------- Retrofit + RxJava2.0 + Kotlin + MVP 开发的 WanAndroid 项目、Android Kotlin RXKotlin Room - 错误 Kotlin.unit、Android O seLinux 编译错误的相关知识,希望对你有所帮助。
本文目录一览:- android-Kotlin类型不匹配编译错误:要求成功,发现MyError(kotlin unresolved reference)
- Android & Kotlin:基于Room、Kotlin协程的MVVM app
- android -------- Retrofit + RxJava2.0 + Kotlin + MVP 开发的 WanAndroid 项目
- Android Kotlin RXKotlin Room - 错误 Kotlin.unit
- Android O seLinux 编译错误
android-Kotlin类型不匹配编译错误:要求成功,发现MyError(kotlin unresolved reference)
我遇到以下问题,无法在kotlin中编译以下代码.
// StateModel.kt
sealed class StateModel
class Loading : StateModel()
data class Success<T: Any>(val data: T) : StateModel()
data class MyError(val message: String) : StateModel()
// StateModelTransformer.kt
class StateModelTransformer<T: Any> : FlowableTransformer<T, StateModel> {
override fun apply(upstream: Flowable<T>): Publisher<StateModel> {
return upstream
.map { data -> Success(data) }
.onErrorReturn { error ->
MyError(error.message) // compile error, Type mismatch, Require Success<T>, Found MyError
}
.startWith(Loading()) // compile error, none of the following function can be called with the arguments supplied
}
}
我不知道为什么onErrorReturn表示需要Success
以下是Flowable中的相关声明,以供参考.让我们忽略onErrorReturn;这与这里的问题无关.
public Flowable<T> {
public <R> Flowable<R> map(Function<? super T, ? extends R> mapper);
public Flowable<T> startWith(T value);
}
这些是Kotlin推断的类型.
val upstream: Flowable<T>
val mapper: (T) -> Success<T> = { data -> Success(data) }
val map: ((T) -> Success<T>) -> Flowable<Success<T>>
= upstream::map
val mapped: Flowable<Success<T>> = map(mapper)
val loading: Loading = Loading()
val startWith:
(Success<T>) -> Flowable<Success<T>>
= mapped::startWith
startWith(loading) // type mismatch
更具体的Success T类型早已被推断出来,并且Kotlin不会回溯找到更通用的StateModel类型.为此,您可以手动声明类型,例如
// be explicit about the general type of the mapper
upstream.map { data -> Success(data) as StateModel }.startWith(Loading())
// be explicit about the generic type R = StateModel
upstream.map<StateModel> { data -> Success(data) }.startWith(Loading())
顺便说一句,您当前正在失去< T>在StateModel中.我建议更改基类以包括type参数.
sealed class StateModel<out T: Any>
object Loading : StateModel<nothing>()
data class Success<T: Any>(val data: T) : StateModel<T>()
data class MyError(val message: String) : StateModel<nothing>()
例如,这可以让您编写,
val <T: Any> StateModel<T>.data: T?
get() = when (this) {
is Success -> data
else -> null
}
相关文章
- android - Kotlin:功能类型不匹配
- Kotlin:防止==类型错误的编译
- java - Android测试类无法在eclipse中编译,并出现“绑定不匹配”错误
- scala - 控制器操作无法编译,发现类型不匹配:需要单位:play.api.mvc.Result“
- scala编译错误:类型不匹配; found:需要IndexedSeq [Int]:scala.collection.immutable.Seq [Int]
- android - Kotlin类型不匹配:推断类型是View!但TextView是预料之中的
- haskell-发出HTTP请求时出现类型不匹配错误
- 单位“回调">scala - 获取“错误:类型不匹配;发现:需要单位:()=>单位“回调
转载注明原文:android-Kotlin类型不匹配编译错误:要求成功,发现MyError - 代码日志
解决方法:
以下是Flowable中的相关声明,以供参考.让我们忽略onErrorReturn;这与这里的问题无关.
public Flowable<T> {
public <R> Flowable<R> map(Function<? super T, ? extends R> mapper);
public Flowable<T> startWith(T value);
}
这些是Kotlin推断的类型.
val upstream: Flowable<T>
val mapper: (T) -> Success<T> = { data -> Success(data) }
val map: ((T) -> Success<T>) -> Flowable<Success<T>>
= upstream::map
val mapped: Flowable<Success<T>> = map(mapper)
val loading: Loading = Loading()
val startWith:
(Success<T>) -> Flowable<Success<T>>
= mapped::startWith
startWith(loading) // type mismatch
更具体的Success T类型早已被推断出来,并且Kotlin不会回溯找到更通用的StateModel类型.为此,您可以手动声明类型,例如
// be explicit about the general type of the mapper
upstream.map { data -> Success(data) as StateModel }.startWith(Loading())
// be explicit about the generic type R = StateModel
upstream.map<StateModel> { data -> Success(data) }.startWith(Loading())
顺便说一句,您当前正在失去< T>在StateModel中.我建议更改基类以包括type参数.
sealed class StateModel<out T: Any>
object Loading : StateModel<nothing>()
data class Success<T: Any>(val data: T) : StateModel<T>()
data class MyError(val message: String) : StateModel<nothing>()
例如,这可以让您编写,
val <T: Any> StateModel<T>.data: T?
get() = when (this) {
is Success -> data
else -> null
}
Android & Kotlin:基于Room、Kotlin协程的MVVM app
本篇主要介绍Android系统通过Room进行CRUD操作,以及使用kotlin协程的处理方法。
0. 效果展示
1. 添加依赖
注释使用kapt
apply plugin: ''kotlin-kapt''
1.1 lifecycle
通过这个可以获取其他组建生命周期变化
- 这里注释使用kapt,选着相应的注释依赖
def lifecycle_version = "2.2.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// 基于kotlin-kapt的注释组建
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
1.2 Room
- Room就好像spring中的jpa,让CRUD更简单
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
// Kotlin 使用 kapt
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room 协程操作库
implementation "androidx.room:room-ktx:$room_version"
1.3 kotlin协程
- 添加coroutines依赖 以及 android协程依赖
// 添加协程安卓库
implementation ''org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9''
implementation ''org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9''
1.4 数据库表导出
- 配置在
defaultConfig
中,将room.schemaLocation
导出
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
1.5 dataBinding
- 需要在配置
android
中激活dataBinding
dataBinding{
enabled = true
}
2. 数据表实现
跟spring的配置差不多,model,dao,sersice这些
2.1 创建一个User类
- User类 对应到
user_table
@PrimaryKey
设置主键先当于spring的@Id
,autoGenerate = true
设置自增@ColumnInfo(name = "user_name")
指定列名
/**
* @author: ffzs
* @Date: 2020/9/11 下午5:05
*/
@Entity(tableName = "user_table")
data class User (
@PrimaryKey(autoGenerate = true)
var id:Long,
@ColumnInfo(name = "user_name")
var name:String,
@ColumnInfo(name = "email")
var email:String
)
2.2 dao实现
@Dao
进行注释@Query
写法跟jpa基本相同
/**
* @author: ffzs
* @Date: 2020/9/11 下午5:08
*/
@Dao
interface UserDao {
@Insert
suspend fun insert (user: User):Long
@Update
suspend fun update (user: User):Int
@Delete
suspend fun delete (user: User):Int
@Query("DELETE FROM user_table")
suspend fun deleteAll ():Int
@Query("SELECT * FROM user_table")
fun findAll ():LiveData<List<User>>
@Query("SELECT * FROM user_table WHERE id = :id")
suspend fun findById (id:Long):User
}
2.3 服务实现
- 主要用来获取数据
class UserRepository(private val dao: UserDao) {
val subscribers = dao.findAll()
suspend fun insert(user: User):Long{
return dao.insert(user)
}
suspend fun update(user: User):Int{
return dao.update(user)
}
suspend fun delete(user: User) : Int{
return dao.delete(user)
}
suspend fun deleteAll() : Int{
return dao.deleteAll()
}
}
2.4 RoomDatabase实现
- 通过伴生对象实现单例模式
entities = [User::class]
,需要实现表的类,通过反射生成数据表
/**
* @author: ffzs
* @Date: 2020/9/11 下午5:15
*/
@Database(entities = [User::class], version = 1)
abstract class UserDatabase : RoomDatabase() {
abstract val userDao: UserDao
// 通过伴生对象实现单例模式
companion object {
@Volatile
private var INSTANCE: UserDatabase? = null
fun getInstance(context: Context): UserDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
UserDatabase::class.java,
"user_table"
).build()
}
return instance
}
}
}
}
- 直接通过getInstance方法获取database实例:
UserDatabase.getInstance(application)
3. databinding实现
3.1 实现ViewModel
- 首先需要实现一个ViewModel,用来绑定参数
/**
* @author: ffzs
* @Date: 2020/9/11 下午4:46
*/
class UserViewModel (private val repository: UserRepository): ViewModel(), Observable {
@Bindable
val inputName = MutableLiveData<String>()
@Bindable
val inputEmail = MutableLiveData<String>()
@Bindable
val btnSave = MutableLiveData<String>()
@Bindable
val btnDel = MutableLiveData<String>()
3.2 activity_main绑定
- 通过layout进行绑定,使用
variable
进行配置
3.3 关联使用
- 变量关联
- 函数关联,像极了前端的回调
3.4 绑定
- 通过下图的方法可以进行绑定,如图所示这里还少一个
factory
3.5 ViewModelProvider.Factory
/**
* @author: ffzs
* @Date: 2020/9/11 下午6:43
*/
class UserViewModelFactory (private val repository: UserRepository): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(UserViewModel::class.java)){
return UserViewModel(repository) as T
}
throw IllegalArgumentException("ViewModel类型不匹配")
}
}
3.6 设置生命周期的归属
- 指定binding的归属
binding.lifecycleOwner = this
3.7 完整绑定代码
val dao = UserDatabase.getInstance(application).userDao
val repository = UserRepository(dao)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
userViewModel = ViewModelProvider(this,UserViewModelFactory(repository)).get(UserViewModel::class.java)
binding.userViewModel = userViewModel
4. RecyclerView实现用户展示
4.1 Holder实现
- 将传入的user信息通过
binding
写到RecyclerView
中 - 以及点击触发效果
/**
* @author: ffzs
* @Date: 2020/9/11 下午7:12
*/
class UserViewHolder (val binding: UserListBinding): RecyclerView.ViewHolder(binding.root){
fun bind(user: User, clickListener:(User)->Unit){
binding.nameTextView.text = user.name
binding.emailTextView.text = user.email
binding.listItemLayout.setOnClickListener{
clickListener(user)
}
}
}
4.2 Adapter实现
用来实现RecyclerView状态的更改
- 通过binding生成holder
onBindViewHolder
操作当前位置元素,并执行操作getItemCount
返回展示数量
/**
* @author: ffzs
* @Date: 2020/9/11 下午7:11
*/
class UserRecyclerViewAdapter(private val clickListener: (User) -> Unit) : RecyclerView.Adapter<UserViewHolder>() {
private val userList = ArrayList<User>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding : UserListBinding =
DataBindingUtil.inflate(layoutInflater,R.layout.user_list,parent,false)
return UserViewHolder(binding)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(userList[position], clickListener)
}
override fun getItemCount(): Int {
return userList.size
}
fun setList(users: List<User>){
userList.clear()
userList.addAll(users)
}
}
5. 协程使用
- insert协程写法,直接通过
viewModelScope
调用协程launch
,在代码块中进行操作 - 感觉跟使用reactor有些相似,主要避免阻塞,dao中使用
suspend
标注异步
private fun insert(subscriber: User) = viewModelScope.launch {
val newRowId = repository.insert(subscriber)
if (newRowId > -1) {
msg.value = Event("$newRowId 成功添加")
} else {
msg.value = Event("添加出错")
}
}
6. debug
6.1 databinding载入失败
配置中需要enable
dataBinding{
enabled = true
}
6.2 javax/xml/bind/JAXBException
- java8以上不自带
xml bind
下图中位置改成java8 - java11写spring还可以,看来写java还有点早
7. 源码
github
android -------- Retrofit + RxJava2.0 + Kotlin + MVP 开发的 WanAndroid 项目
简介
wanandroid 项目基于 Retrofit + RxJava2.0 + Kotlin + MVP
implementation ''io.reactivex.rxjava2:rxjava:2.1.3''
implementation ''com.squareup.retrofit2:retrofit:2.3.0''
implementation ''com.squareup.retrofit2:converter-gson:2.3.0''
implementation ''com.squareup.retrofit2:adapter-rxjava2:2.3.0''
implementation ''io.reactivex.rxjava2:rxandroid:2.0.1''
implementation ''com.github.bumptech.glide:glide:3.7.0''
implementation ''cn.bingoogolapple:bga-banner:2.2.4''
implementation ''com.just.agentweb:agentweb:1.0.3''
/** loading状态组件 **/
implementation ''com.github.ybq:Android-SpinKit:1.1.0''
/**状态栏**/
implementation ''com.gyf.barlibrary:barlibrary:2.3.0''
implementation ''com.hyman:flowlayout-lib:1.1.2''
implementation ''com.alibaba:fastjson:1.1.68.android''
有下拉刷新 SmartRefreshLayout
效果图
玩 Android 的 Api 是免费的,感谢 WanAndroid 提供的数据来源
鸿洋大佬提供的 API 接口 http://www.wanandroid.com/blog/show/2
项目地址: https://github.com/DickyQie/wanandroid
Android Kotlin RXKotlin Room - 错误 Kotlin.unit
如何解决Android Kotlin RXKotlin Room - 错误 Kotlin.unit?
我想通过循环数组向房间数据库做一个简单的插入数据。 我使用 RXKotlin 来迭代数组 我有一个这样的数组:
fun defaultDataCategory() : ArrayList<CategoryModel>{
var cat: CategoryModel
var catArrayList: ArrayList<CategoryModel> = ArrayList(0)
val date: Int = Calendar.DATE
val formatedDate = SimpleDateFormat("yyyy-MM-dd").format(Date())
val formatedTime = SimpleDateFormat("HH:mm").format(Date())
val DateTime = "$formatedDate $formatedTime"
catArrayList.add(
CategoryModel(
1,"Personal",true,"Red",Converter.toDate(Calendar.getInstance().timeInMillis),"system","system"
)
)
catArrayList.add(
CategoryModel(
2,"Work","Blue","system"
)
)
catArrayList.add(
CategoryModel(
3,"Home","Purple","system"
)
)
catArrayList.add(
CategoryModel(
4,"Learn","Yellow","system"
)
)
return catArrayList
}
我像这样用 RXKotlin 循环了一个数组
var catArrayList: ArrayList<CategoryModel> = DefaultData.defaultDataCategory()
catArrayList.toObservable()
.subscribeBy( // named arguments for lambda Subscribers
onNext = { homeviewmodel.insertCategory(it) },onError = { Log.e("error insert=",it.printstacktrace().toString()) },onComplete = { Log.e("complete insert=","complete insert") }
)
我得到了一个错误“kotlin.unit”。
Error RXKotlin
如何使用 RXKotlin 迭代数组并插入房间数据库?
解决方法
试试
Observable.fromIterable(catArrayList).subscribeBy {...}
Android O seLinux 编译错误
编译 android O 源码,遇到错误
FAILED: out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy
/bin/bash -c "(out/host/linux-x86/bin/secilc -M true -G -c 30 out/target/product/hon450/obj/ETC/plat_sepolicy.cil_intermediates/plat_sepolicy.cil out/target/product/hon450/obj/ETC/27.0.cil_intermediates/27.0.cil out/target/product/hon450/obj/ETC/nonplat_sepolicy.cil_intermediates/nonplat_sepolicy.cil -o out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy.tmp -f /dev/null ) && (out/host/linux-x86/bin/sepolicy-analyze out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy.tmp permissive > out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy.permissivedomains ) && (if [ \"userdebug\" = \"user\" -a -s out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy.permissivedomains ]; then echo \"==========\" 1>&2; echo \"ERROR: permissive domains not allowed in user builds\" 1>&2; echo \"List of invalid domains:\" 1>&2; cat out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy.permissivedomains 1>&2; exit 1; fi ) && (mv out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy.tmp out/target/product/hon450/obj/ETC/sepolicy_intermediates/sepolicy )"
neverallow check failed at out/target/product/hon450/obj/ETC/nonplat_sepolicy.cil_intermediates/nonplat_sepolicy.cil:4181
(neverallow base_typeattr_49_27_0 netd_27_0 (unix_stream_socket (connectto)))
<root>
allow at out/target/product/hon450/obj/ETC/nonplat_sepolicy.cil_intermediates/nonplat_sepolicy.cil:7695
(allow WifiLogger_app netd_27_0 (unix_stream_socket (connectto)))
neverallow check failed at out/target/product/hon450/obj/ETC/plat_sepolicy.cil_intermediates/plat_sepolicy.cil:4696 from system/sepolicy/public/domain.te:586
(neverallow base_typeattr_49 netd (unix_stream_socket (connectto)))
<root>
allow at out/target/product/hon450/obj/ETC/nonplat_sepolicy.cil_intermediates/nonplat_sepolicy.cil:7695
(allow WifiLogger_app netd_27_0 (unix_stream_socket (connectto)))
Failed to generate binary
由于我自己添加了 te 文件中内容与系统冲突。如下所示:
allow WifiLogger_app netd:unix_stream_socket connectto;
解决办法,删除上面的语句,添加
net_domain(WifiLogger_app)
unix_socket_connect(WifiLogger_app, netd, netd);
Tony Liu
2018-3-12
关于android-Kotlin类型不匹配编译错误:要求成功,发现MyError和kotlin unresolved reference的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Android & Kotlin:基于Room、Kotlin协程的MVVM app、android -------- Retrofit + RxJava2.0 + Kotlin + MVP 开发的 WanAndroid 项目、Android Kotlin RXKotlin Room - 错误 Kotlin.unit、Android O seLinux 编译错误等相关内容,可以在本站寻找。
本文标签: