I'm trying to save object in background by using Parse.com but I can't override
override fun done(e: ParseException?) {
//code
}
I'm getting error: Modifier 'override' is not applicable to 'local function
In java I would use:
myObject.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
myObjectSavedSuccessfully();
} else {
myObjectSaveDidNotSucceed();
}
}
});
Here is my whole class
class StarterApplication : Application() {
override fun onCreate() {
super.onCreate()
Parse.initialize(Parse.Configuration.Builder(this)
.applicationId(appID)
.clientKey(null)
.server(serverUrl)
.build()
)
var exampleObject: ParseObject = ParseObject("ExampleObject")
exampleObject.put("myString", "fwfwe")
exampleObject.saveInBackground( {
override fun done(e: ParseException?) { //here is an error //`Modifier 'override' is not applicable to 'local function`
}
})
}
}
Just do like that:
exampleObject.saveInBackground(object : SaveCallback {
override fun done(e: ParseException?) {
// Add your code here
}
})
In Java, you declare an anonymous class that extend SaveCallback. In Kotlin, you do this with Object Expressions.
you can also try the simplest solution like this
exampleObject.saveInBackground({
//you code here
})
https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
Related
I have been using a network check functionality in-app, but all things are available in Kotlin now the same thing wants to integrate in java facing some issue related to lazy calling.
This is how I can check network state in Kotlin
class MainActivity : AppCompatActivity(), ConnectivityStateListener {
private lateinit var tv: TextView
private val provider: ConnectivityProvider by lazy { ConnectivityProvider.createProvider(this) }
#RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv = findViewById(R.id.connectivity_state)
val button = findViewById<View>(R.id.button)
val currentState = findViewById<TextView>(R.id.current_state)
button.setOnClickListener {
val hasInternet = provider.getNetworkState().hasInternet()
currentState.text = "Connectivity (synchronously): $hasInternet"
}
}
override fun onStart() {
super.onStart()
provider.addListener(this)
}
override fun onStop() {
super.onStop()
provider.removeListener(this)
}
override fun onStateChange(state: NetworkState) {
val hasInternet = state.hasInternet()
tv.text = "Connectivity (via callback): $hasInternet"
}
private fun NetworkState.hasInternet(): Boolean {
return (this as? ConnectedState)?.hasInternet == true
}
}
this is how I integrated into Java
#Override
protected void onStart() {
super.onStart();
provider=ConnectivityProvider.createProvider(this);
provider.addListener(this);
}
#Override
protected void onStop() {
super.onStop();
provider.removeListener(this);
}
#Override
public void onStateChange(#NotNull ConnectivityProvider.NetworkState state) {
Log.d("To ConnectivityProvider-----", state.toString());
Toast.makeText(LoginActivity.this, "Available", Toast.LENGTH_SHORT).show();
if( hasInternet(state)){
Toast.makeText(LoginActivity.this, "Available", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(LoginActivity.this, "No Internet", Toast.LENGTH_SHORT).show();
}
}
private boolean hasInternet(#NotNull ConnectivityProvider.NetworkState state) {
ConnectivityProvider.NetworkState.ConnectedState var2 = (ConnectivityProvider.NetworkState.ConnectedState)state;
if (var2.getHasInternet()) {
return true;
}
return false;
}
java.lang.ClassCastException:
com.ro.other.connectivity.base.ConnectivityProvider$NetworkState$NotConnectedState
cannot be cast to
com.ro.other.connectivity.base.ConnectivityProvider$NetworkState$ConnectedState
gitlink help me to integrate this in java
The problem here is with type casting, not with lazy calling. The behaviour of the hasInternet methods in the given Kotlin and Java code is different.
Kotlin:
return (this as? ConnectedState)?.hasInternet == true
If the current NetworkState is not a ConnectedState, the typecast this as? ConnectedState will return null, and the method will return false.
Java:
ConnectivityProvider.NetworkState.ConnectedState var2 = (ConnectivityProvider.NetworkState.ConnectedState)state;
if (var2.getHasInternet()) {
return true;
}
return false;
This code assumes that state is a ConnectedState (instead of checking it), and throws a ClassCastException if it is an instance of a different class.
The correct Java code for hasInternet method would be:
if (!(state instanceof ConnectivityProvider.NetworkState.ConnectedState)) {
return false;
}
ConnectivityProvider.NetworkState.ConnectedState var2 = (ConnectivityProvider.NetworkState.ConnectedState)state;
if (var2.getHasInternet()) {
return true;
}
return false;
Hi everyone I have the following problem when I run my project on Intellij everything works fine but when i make the build using maven install and run my project appears this issue.
[Failed to evaluate expression 'isAuthenticated()
&& isPermitted('domain:read:*')'][1]
[1]: https://i.stack.imgur.com/LkaY6.png
my code
#PreAuthorize("isAuthenticated() && isPermitted('domain:read:*')")
#GetMapping(produces = [(MediaType.APPLICATION_JSON_VALUE)])
fun search(query: DomainQuery): ResponseEntity<ArpiaPage<DomainOutput>> {
val retval = service.search(query)
return ResponseEntity(
retval.map { domain -> converter.convert(domain, DomainOutput::class.java) },
HttpStatus.OK
)
}
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled=true)
class ShiroMethoSecurityConfig : GlobalMethodSecurityConfiguration() {
override fun createExpressionHandler(): MethodSecurityExpressionHandler {
return ShiroMethodSecurityExpressionHandler()
}
}
class ShiroMethodSecurityExpressionHandler : DefaultMethodSecurityExpressionHandler() {
private val trustResolver = AuthenticationTrustResolverImpl()
override fun createSecurityExpressionRoot(authentication: Authentication, invocation: MethodInvocation): MethodSecurityExpressionOperations {
return ShiroMethodSecurityExpressionRoot(authentication).apply {
setPermissionEvaluator(permissionEvaluator)
setTrustResolver(trustResolver)
setRoleHierarchy(roleHierarchy)
}
}
}
open class ShiroMethodSecurityExpressionRoot(authentication: Authentication) : SecurityExpressionRoot(authentication), MethodSecurityExpressionOperations {
private var filterObject: Any? = null
private var returnObject: Any? = null
private var target: Any? = null
private val LOG = LoggerFactory.getLogger(ShiroMethodSecurityExpressionRoot::class.java)
override fun setFilterObject(filterObject: Any) {
this.filterObject = filterObject
}
override fun getFilterObject(): Any? {
return filterObject
}
override fun setReturnObject(returnObject: Any) {
this.returnObject = returnObject
}
override fun getReturnObject(): Any? {
return returnObject
}
/**
* Sets the "this" property for use in expressions. Typically this will be the "this"
* property of the `JoinPoint` representing the method invocation which is being
* protected.
*
* #param target the target object on which the method in is being invoked.
*/
fun setThis(target: Any) {
this.target = target
}
override fun getThis(): Any? {
return target
}
#Bean
open fun isPermitted(permission: String?): Boolean {
return true
}
#Bean
fun isPermitted(vararg permissions: String): Boolean {
return try {
val permissionObjects = permissions.map { permission -> WildcardPermission(permission) }
val user = this.principal as AuthAccount
//true
permissionObjects.all {
user.permissions.any { permission ->
permission.implies(it)
}
}
} catch (e: Exception) {
e.printStackTrace()
LOG.debug("", e)
throw (e)
}
}
}
Try to use text 'and' in the place of logical operator '&&'. I believe in #PreAuthorize annotation, you need to give text to combine multiple checks
I am wondering what is the best way to unify the response type returned from both a room db and an API. Basically I am trying to get a list of Movie objects
Because of the API response design, I have to wrap the results in a Observable<MovieResponse> object
data class MovieResponse(#SerializedName("total_results") var totalResults: Int,
#SerializedName("total_pages") var totalPages: Int,
#SerializedName("results") var results: List<Movie>) {
}
So, then I can store the Movies in a local Room database, so the result from querying the DB is a Observable<List<Movie>> object.
This is forcing me of having 2 different methods (almost the same) to subscribe to both the API and DB responses
private fun subscribeMovies(moviesObservable: Observable<MovieResponse>) {
disposable.add(moviesObservable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableObserver<MovieResponse>() {
override fun onComplete() {
}
override fun onError(e: Throwable) {
e.printStackTrace()
}
override fun onNext(movieResponse: MovieResponse) {
// do stuff
}
}))
}
private fun subscribeMoviesFromDB(moviesObservable: Observable<List<Movie>>) {
disposable.add(moviesObservable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableObserver<List<Movie>>() {
override fun onComplete() {
}
override fun onError(e: Throwable) {
e.printStackTrace()
}
override fun onNext(movies: List<Movie>) {
//do stuff
}
}))
}
Any advice on how to deal with this properly?
Thanks
You could make some sort of class that extends what you need. I'm not sure about the physical subscriptions, but at the very least you could make a generic class that you can throw into the subscribeWith() function that's not redundant.
How about something like this? (Sorry I don't know kotlin, so here's a java equivalent):
public class MyObserver<T> extends DisposableObserver<T> {
#Override
public void onComplete() {
}
#Override
public void onError(Throwable e) {
e.printStackTrace()
}
#Override
public void onNext(T response) {
// do stuff
}
}
Then you could in theory call it in each of your subscriptions like such:
disposable.add(moviesObservable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : MyObserver<List<Movie>>() {
I´ve been looking for a suitable solution or best practice when I want to use Kotlin Flows with ordinary callbacks. My use case is that I write a kotlin library that uses Kotlin Flow internally and i have to assume that the users will use Java for instance. So I thought that the best solution is to overload a basic callback interface to my flow method and call it in collect something like this:
class KotlinClass {
interface Callback {
fun onResult(result: Int)
}
private fun foo() = flow {
for (i in 1..3) {
emit(i)
}
}
fun bar(callback: Callback) {
runBlocking {
foo().collect { callback.onResult(it) }
}
}
private fun main() {
bar(object : Callback {
override fun onResult(result: Int) {
TODO("Not yet implemented")
}
})
}
and in my Java Application i can simply use it like that:
public class JavaClass {
public void main() {
KotlinClass libraryClass = new KotlinClass();
libraryClass.bar(new KotlinClass.Callback() {
#Override
public void onResult(int result) {
// TODO("Not yet implemented")
}
});
}
}
I am not sure whats the way to go because I would like to have my Kotlin library that uses Flows usable in a good fashion for Java and Kotlin.
I came across callbackFlow but that seems to be only if I want to let´s call it flow-ify a callback-based API? Because I am quite new to Kotlin and Flows please apologise if my question is flawed in cause of missing some basic concepts of kotlin.
I would give the Java client more control over the flow. I would add a onStart and onCompletion method to your callback interface. Beside this I would use an own CoroutineScope - maybe customizable from the Java client. And I would not block the calling thread from within the Kotlin function - no runBlocking.
#InternalCoroutinesApi
class KotlinClass {
val coroutineScope = CoroutineScope(Dispatchers.Default)
interface FlowCallback {
#JvmDefault
fun onStart() = Unit
#JvmDefault
fun onCompletion(thr: Throwable?) = Unit
fun onResult(result: Int)
}
private fun foo() = flow {
for (i in 1..3) {
emit(i)
}
}
fun bar(flowCallback: FlowCallback) {
coroutineScope.launch {
foo().onStart { flowCallback.onStart() }
.onCompletion { flowCallback.onCompletion(it) }
.collect { flowCallback.onResult(it) }
}
}
fun close() {
coroutineScope.cancel()
}
}
Now the Java client is in full control how to start, collect and cancel the flow. For example you could use a latch to wait for completion, set an timeout and cancel the couroutine scope. This looks in the first place like a lot of code, but typically you will need this kind of flexibility.
public class JavaClass {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
KotlinClass libraryClass = new KotlinClass();
libraryClass.bar(new KotlinClass.FlowCallback() {
#Override
public void onCompletion(#Nullable Throwable thr) {
latch.countDown();
}
#Override
public void onResult(int result) {
System.out.println(result);
}
});
try {
latch.await(5, TimeUnit.SECONDS);
} finally {
libraryClass.close();
}
}
}
You don't need to create a interface in the Kotlin code. You can define bar like that:
fun bar(callback: (Int) -> Unit) {
runBlocking {
foo().collect { callback(it) }
}
}
From the Java code you can call the function like that:
public class JavaClass {
public static void main(String[] args) {
KotlinClass libraryClass = new KotlinClass();
libraryClass.bar(v -> { System.out.println(v); return Unit.INSTANCE; });
}
}
In case anyone wondering for a general solution. Here's our version of enhancement from #rene answer here.
Accept a generic type
A configurable coroutineScope
// JavaFlow.kt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
#InternalCoroutinesApi
class JavaFlow<T>(
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) {
interface OperatorCallback <T> {
#JvmDefault
fun onStart() = Unit
#JvmDefault
fun onCompletion(thr: Throwable?) = Unit
fun onResult(result: T)
}
fun collect(
flow: Flow<T>,
operatorCallback: OperatorCallback<T>,
) {
coroutineScope.launch {
flow
.onStart { operatorCallback.onStart() }
.onCompletion { operatorCallback.onCompletion(it) }
.collect { operatorCallback.onResult(it) }
}
}
fun close() {
coroutineScope.cancel()
}
}
Java caller-side:
// code omitted...
new JavaFlow<File>().collect(
// compressImageAsFlow is our actual kotlin flow extension
FileUtils.compressImageAsFlow(file, activity),
new JavaFlow.OperatorCallback<File>() {
#Override
public void onResult(File result) {
// do something with the result here
SafeSingleton.setFile(result);
}
}
);
// or using lambda with method references
// new JavaFlow<File>().collect(
// FileUtils.compressImageAsFlow(file, activity),
// SafeSingleton::setFile
// );
// Change coroutineScope to Main
// new JavaFlow<File>(CoroutineScopeKt.MainScope()).collect(
// FileUtils.compressImageAsFlow(file, activity),
// SafeSingleton::setFile
// );
OperatorCallback.onStart and OperatorCallback.onCompletion is optional, override it as needed.
I have the following Java class I'm trying to convert to Kotlin that uses generics.
abstract class MvpViewHolder, M, V : View?>(itemView: View) : RecyclerView.ViewHolder(itemView) {
public abstract class MvpViewHolder<P extends BasePresenter> extends RecyclerView.ViewHolder {
protected P presenter;
public MvpViewHolder(View itemView) {
super(itemView);
}
public void bindPresenter(P presenter) {
this.presenter = presenter;
presenter.bindView(this);
}
public void unbindPresenter() {
presenter = null;
}
}
Here is my Kotlin attempt
abstract class MvpViewHolder<P : BasePresenter>(itemView: View) : RecyclerView.ViewHolder(itemView) {
protected var presenter: P? = null
fun bindPresenter(presenter: P?): Unit {
this.presenter = presenter
presenter?.bindView(this)
}
fun unbindPresenter(): Unit {
this.presenter = null
}
}
I'm particularly running into a problem with the generics. It turns out that in Kotlin it's simply not enough to do MvpViewHolder<P : BasePresenter> as Kotlin requires that we pass in the 2 type arguments for BasePresenter (whose implementation I put below)
However, if I need to pass in the type arguments for BasePresenter then my method signature would then look like this
`abstract class MvpViewHolder<P : BasePresenter<*, *>>(itemView: View) : RecyclerView.ViewHolder(itemView) {`
This does not help me however, because in presenter.bindView(this) I get a type error of Required: Nothing, Found: MvpViewHolder
I could also get more specific and pass in
MvpViewHolder<P: BasePresenter<M, V>, M, V> but then that would mean that wherever I call MvpViewHolder, I then also have to include 2 extra type parameters. Not only will that be tedious to deal with now having to maintain, but it just makes me sad.
How can I either get rid of the error when I use BasePresenter<,> or avoid having to pass in 3 type parameters into my MvpViewHolder class, just so I can define P as a BasePresenter
abstract class BasePresenter<M, V> {
var model: M? = null
var view: WeakReference<V>? = null
fun setM(model: M?): Unit {
this.model = model
if (setupDone()) {
updateView()
}
}
fun bindView(view: V) {
this.view = WeakReference(view)
}
fun unbindView() {
this.view = null
}
abstract fun updateView()
fun view(): V? {
return if (view == null) null else view?.get()
}
fun setupDone(): Boolean {
return view() != null && model != null
}
}
Change abstract class to the following code
abstract class MvpViewHolder<P :BasePresenter<P,MvpViewHolder<P>>>(itemView: View) : RecyclerView.ViewHolder(itemView) {
protected var presenter: P? = null
fun bindPresenter(presenter: P) {
this.presenter = presenter
presenter.bindView(this)
}
fun unbindPresenter() {
presenter = null
}
}