Keep execution context on permission requested #39
Conversation
… the calling thread till the permission listener is called
…racted the way of create a ThreadSpec inside the factory.
… handle needs a thread with a looper before it is created
…c00022/Dexter into feature/simplify_thread_specs Conflicts: dexter/src/main/java/com/karumi/dexter/listener/threaddecorator/ThreadSpecFactory.java dexter/src/main/java/com/karumi/dexter/listener/threaddecorator/WorkerThreadSpec.java
…er instead of the decorator subclass that is later instantiated on this field
…"checkPermission" methods
Conflicts: dexter/src/main/java/com/karumi/dexter/DexterInstance.java
Conflicts: dexter/src/main/java/com/karumi/dexter/DexterInstance.java
Thanks for your PR @cmc00022 I'll take a look this week :) |
/** | ||
* A thread specification to execute passed runnable objects in the main thread | ||
*/ | ||
class MainThreadSpec implements ThreadSpec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This thread spec doesn't run anything on the main thread. It's relying on where it is being executed to run it in that very same thread but doesn't force to be the main thread in any way. I'd either rename it or move the logic to run things on the main thread to this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @Serchinastico says, if you want to force the execution over the main thread you should create a handler using the main looper.
/** | ||
* Decorator to execute the permission updates on a given thread specification | ||
*/ | ||
public class MultiplePermissionListenerThreadDecorator implements MultiplePermissionsListener { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talking to @Serchinastico we've just noticed that this listener is public :S This should be an implementation detail, the usage of this listener should be an internal detail. We should change the interface visibility to default and refactor the current implementation to hide the usage of this interface. Sorry, we didn't see this before :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say the same about the ThreadSpec
interface, it doesn't make sense to expose that part of the library. As I see it we are adding a new abstraction for no real benefit. Users of the library can actually wrap their listeners to execute its callbacks using any android/custom abstraction, with that interface we would be forcing them to understand yet another concept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pedrovgs what do you suggest then? The only reason it's public is because its package is not the same as the DexterInstance
once, where the decorator is used. I could just move the decorator to the DexterInstance
package.
The same issue happens with other classes situated under the threaddecorator
package, such as: ThreadSpecFactory
and ThreadSpec
.
Let me know how you'd like to approach it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the Java visibility mechanism the only option we have is to move all the new code to the DexterInstance
package :( Talking to @Serchinastico we prefer to put all this code together than to expose public APIs. The rest of the listener are thoughts to be used by the library user, but the new one you've added should be hidden to the library user to reduce the library complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@cmc00022 the change you suggest here:
Is not needed. By convention we return the response over the UI thread and thats enough. We don't need to introduce a new method. |
ok, agree. |
Hi guys, about this comment:
Do you really want to have a "Thread" class that the name collides with the "java.lang.Thread"?. |
The If you review the usage of this interface: @Override public void execute(Runnable runnable) {
if (runningMainThread()) {
runnable.run();
} else {
new Handler(Looper.getMainLooper()).post(runnable);
}
} We are using this Due to the main reason to create this abstraction is just for testing purposes we should try to remove the abstraction and create a class HandlerFactory {
Handler getHandler() {
if (runningMainThread()) {
return new Handler();
} else {
return new Handler(Looper.myLooper());
}
}
private boolean runningMainThread() {
return Looper.getMainLooper().getThread() == java.lang.Thread.currentThread();
}
} Doing this we could reduce the amount of code needed and also replace the instance obtained during the Right now I see that @cmc00022 has already changed the interface name from ThreadSpec to Thread, so I'm ok with this change. If we keep the usage of these classes as an implementation detail inside the library we can change it in the future. This is the key in this PR. |
} | ||
|
||
private static boolean runningMainThread() { | ||
return Looper.getMainLooper().getThread() == java.lang.Thread.currentThread(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want, you can remove the usage of java.lang.Thread.currentThread()
changing this if to something like:
return Looper.myLooper() == Looper.getMainLooper()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@cmc00022 please, let me know once you've applied all the changes we've suggested to perform the last PR review :) Thanks for your time and patience. |
Hey @pedrovgs If you are happy with the new name it is ok. |
@cmc00022 please, let me know once you've applied all the changes we've suggested to perform the last PR review :) Thanks for your time and patience. |
private final MultiplePermissionsListener listener; | ||
private final Thread thread; | ||
|
||
public MultiplePermissionListenerThreadDecorator(MultiplePermissionsListener listener, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should change the visibility of this constructor to default
instead of public
as we've done with the class signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
After the last PR review I think this PR is ready. Please review the last comments I've added about some methods visibility, Please @flipper83 I need another 👍. Review this PR carefully. |
@flipper83 do we have your ok? If you can't review this PR just tell me to ask to Sergio if he has time. |
Sorry I'm come back from my holidays yesterday. ok with pedro comments 👍 to the PR. |
Thank you guys! I'm going to merge this PR and release a new version. |
Keep execution context on permission requested
@pedrovgs here is the PR to keep the execution context.
As you pointed out to add a public method to keep the execution context I did so.
But there is another possibility. We could use the old DexterInstance.checkPermission() method to just return the listener callbacks on the same thread that calls the method.
If you rather go for the 2 public methods option, then I'd rename the old DexterInstance.checkPermission() to DexterInstance.checkPermissionOnMainThread(), as the method to check permission on the same thread is called DexterInstance.checkPermissionOnSameThread(). I think this will make more evident the purpose of both methods.
Thanks.
Fix #31