Re: [android-developers] INSTALL_FAILED_DUPLICATE_PERMISSION
I'm seeing this with android:protectionLevel=normal too. Since Android doesn't grant permissions that had not been declared yet, this forces the user to install apps declaring / using the permission in a certain order. This is a pain for the user, so the developer of one app that works with mine (and needs a permission declared there) added an identical permission declaration stanza in his app too. A clever hack, on Android prior to 5.0, it lets the user install mine and his apps in either order. Since Android 5.0, only one app can be installed at a time -- trying to install the other one fails with Play error code 505. I don't work for Google, so can only post a link to the bug tracker -- https://code.google.com/p/android/issues/detail?id=79375 -- and maybe recommend trying signature protection level, since both apps are yours and (as I understand) you hadn't released the new one yet, so you can still make that change. -- K On Friday, February 20, 2015 at 11:33:25 AM UTC+3, marten wrote: Hi Marina, we're using android:protectionLevel=dangerous because that's what we think is suitable for personal data like tasks. Also, it's what the CalendarProvider uses for the permissions to read and write calendars. At present the major issue is that some users get this error even though they install the properly signed version from Google Play. The root of all this is that there is no way to grant a permission that hasn't been granted at installation time. And Google is making it worse instead of fixing it. At present the only solution seems to be to use no permissions at all and that's certainly not what this is intended for. If there is someone from Google in this Forum: How is this intended to work? thanks Marten Am Donnerstag, 19. Februar 2015 19:21:40 UTC+1 schrieb Marina Cuello: Hi! I'm not sure how to help, because've only met this problem when there are several users set on a device. If I install my app directly from Eclipse with my debug certificates, then uninstall the app and try to install a production copy, made with the release certificate, I've got the same error message INSTALL_FAILED_DUPLICATE_PERMISSION. Until I uninstall the app in every user by hand, I can't install the new one. At least in your case the error message makes sense :) When I was trying to understand that error message, I've read that it affected permissions with android:protectionLevel declared as signature. Are you using that? Can you change it to normal without affecting your business model? Marina On Wed, Feb 18, 2015 at 11:58 AM, Marten Gajda mar...@dmfs.org wrote: Hi all, we've some problems with Android 5. There seems to be a new policy that requires two apps that define the same permissions to be signed by the same key. Otherwise you can't install the app getting the error INSTALL_FAILED_DUPLICATE_PERMISSION. This is very annoying and I'd like to know that the suggested solution/workaround to this is. We have an Open Source task app that provides access to the tasks via a ContentProvider. The concept pretty much equals the CalendarProvider. We also have a (not yet Open Source) sync app that can sync to this task app (or its ContentProvider). The problem is that (in contrast to the CalendarProvider) our users usually install the sync app first. That means the permissions of the task app are not known when the sync app is installed. So they are not granted automatically when the task app is installed afterwards. Until Android 5 the solution was to define the same permissions in the sync app. But that doesn't work any more in some cases. If the user compiles the task app himself he can not use our sync app at the same time, because they are not signed by the same key. How can we achieve that we protect access to the task ContentProvider by permissions still allowing them to use a self compiled version? Even if both apps are signed by the same key it doesn't seem to work in some cases (does Android 5 also require both apps to be from the same source?) A similar issue exists when another developer tries to build a sync app that can sync to our task app. He can not add the same permissions, because he can't use the same signing key. But if he can't add the same permission definition his app won't get the permission if it's installed before the task app is installed. What's the solution of this mess? thanks Marten -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this
Re: [android-developers] Which pattern is most common for apps that involve communication with servers?
You know, I don't. My apps aren't open source, and I came up with it myself, not borrowed from a library. But it's not rocket science, I'm sure you understand the pattern. -- K On Friday, February 20, 2015 at 4:39:32 AM UTC+3, Kristopher Micinski wrote: I agree, that sounds like a useful pattern. I *think* that's relatively close to how Volley is implemented (though I haven't read the implementation fully), too. Do you have any pointers to open sourced code that would provide an example of such a behavior? If not, no big deal: I can certainly write one myself, and am not asking you to open-source code from your codebase. Kris On Thu, Feb 19, 2015 at 4:17 PM, Kostya Vasilyev kman...@gmail.com javascript: wrote: A service turned inside out A mediator class that manages a pool of threads, submits / cancels / executes task objects, manages the wake lock (based on having tasks). And a service whose only responsibility is to do startForeground / stopForeground when it's told to. All in the same process. This way I don't have to bind to a service (which is asynchronous) and it's easier to manage state in the UI, to indicate to the user what the app is doing, and to queue up tasks when necessary. -- K -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [android-developers] INSTALL_FAILED_DUPLICATE_PERMISSION
Hi Marina, we're using android:protectionLevel=dangerous because that's what we think is suitable for personal data like tasks. Also, it's what the CalendarProvider uses for the permissions to read and write calendars. At present the major issue is that some users get this error even though they install the properly signed version from Google Play. The root of all this is that there is no way to grant a permission that hasn't been granted at installation time. And Google is making it worse instead of fixing it. At present the only solution seems to be to use no permissions at all and that's certainly not what this is intended for. If there is someone from Google in this Forum: How is this intended to work? thanks Marten Am Donnerstag, 19. Februar 2015 19:21:40 UTC+1 schrieb Marina Cuello: Hi! I'm not sure how to help, because've only met this problem when there are several users set on a device. If I install my app directly from Eclipse with my debug certificates, then uninstall the app and try to install a production copy, made with the release certificate, I've got the same error message INSTALL_FAILED_DUPLICATE_PERMISSION. Until I uninstall the app in every user by hand, I can't install the new one. At least in your case the error message makes sense :) When I was trying to understand that error message, I've read that it affected permissions with android:protectionLevel declared as signature. Are you using that? Can you change it to normal without affecting your business model? Marina On Wed, Feb 18, 2015 at 11:58 AM, Marten Gajda mar...@dmfs.org javascript: wrote: Hi all, we've some problems with Android 5. There seems to be a new policy that requires two apps that define the same permissions to be signed by the same key. Otherwise you can't install the app getting the error INSTALL_FAILED_DUPLICATE_PERMISSION. This is very annoying and I'd like to know that the suggested solution/workaround to this is. We have an Open Source task app that provides access to the tasks via a ContentProvider. The concept pretty much equals the CalendarProvider. We also have a (not yet Open Source) sync app that can sync to this task app (or its ContentProvider). The problem is that (in contrast to the CalendarProvider) our users usually install the sync app first. That means the permissions of the task app are not known when the sync app is installed. So they are not granted automatically when the task app is installed afterwards. Until Android 5 the solution was to define the same permissions in the sync app. But that doesn't work any more in some cases. If the user compiles the task app himself he can not use our sync app at the same time, because they are not signed by the same key. How can we achieve that we protect access to the task ContentProvider by permissions still allowing them to use a self compiled version? Even if both apps are signed by the same key it doesn't seem to work in some cases (does Android 5 also require both apps to be from the same source?) A similar issue exists when another developer tries to build a sync app that can sync to our task app. He can not add the same permissions, because he can't use the same signing key. But if he can't add the same permission definition his app won't get the permission if it's installed before the task app is installed. What's the solution of this mess? thanks Marten -- Marten Gajda Schandauer Straße 34 01309 Dresden Germany tel: +49 177 4427167 email: mar...@dmfs.org javascript: twitter: twitter.com/dmfs_org VAT Reg. No.: DE269072391 -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-d...@googlegroups.com javascript: To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To
Re: [android-developers] Re: Which pattern is most common for apps that involve communication with servers?
The main hypothesis I'm wondering about is how developers pass data from their app to the network. Since any use of the network necessarily involves threads, there are a variety of ways this could occur. Most of the ways with which I'm familiar utilize methods where the communication between the app and the network happen with something pretty straightforward. (As an example, in Volley, the threads are somewhat hidden in the request order, and you build up request objects to send to them.) The thing I *don't* want to see is a lot of use of shared variable concurrency to coordinate stuff with a `Thread` instance that is passed to the network, but it doesn't seem like that pops up all that often. Kris On Fri, Feb 20, 2015 at 1:21 PM, erdo e...@ixpocket.com wrote: Sorry for the huge post, but for what it's worth, every app that I do nowadays has the same general pattern... I basically have a model class(es) that incorporates any logic or data that you don't want cluttering up your views/activities/fragments and where you would do any networking stuff. By model I mean the M in MVC or the M in MVVM or the VM in MVVM. (Let's say an account object) You can inject this model class into your views/activities/fragments when you need it - using dagger or you can just roll your own dependency injection code via the application class. That means that the fragment/activity classes just manage their lifecycle and get references to whatever models they need (an account object, maybe a network state object or whatever) and do as little else as possible. When you update the UI, you just run a syncView() method on the fragment or your custom view class (my preference, as it removes even more code from the fragment) that sets the state of all the UI components eg: textView.setText(account.getAccountName()); you just need to make sure all the get() methods on your models return immediately. Any network connectivity or other stuff that needs to be done on a separate thread, I would do from the model class which mostly exists independently of any activity/fragment lifecycle (saving you a whole heap of lifecycle trouble). Once the network stuff has returned with data or an error to the model class, I use the Observer pattern so that the views/activities/fragments or other models that are interested, get notified of the change to the model and then update themselves based on the model's new data (see the syncView() method above). You can roll your own simple observer classes (my preference) or use something like RxJava or even Otto can be used this way. Also if you send all your update notifications on the UI thread, you'll save yourself some headaches when updating UIs based on them. So the models themselves will make use of Volley or Retrofit/OKHttp (both are pretty good and I would definitely use one of them) and may have AsyncTasks in there too. You just have to make sure (especially when using AsyncTasks) that you can independently test the models which means being able to inject the networking stuff (substituting mocked versions for tests). The way AsyncTask is designed makes it particularly awkward to test. You can: Write complicated tests to handle the threading problems using a latch and so on; Test only using a framework like espresso (but then you will be testing via the UI and not strictly doing a unit test; Or you can wrap AsyncTask in your own class that can be used in a synchronous way for tests - that's what I do and it makes the tests much simpler. If you're fetching lists of stuff, I'd use the model classes to write straight to a database once the data has been fetched from the network. ContentLoaders while they do clutter up your fragment/activity code, do seem nice and performant and have a built in observer style mechanism so when the data in your database changes, your view gets immediately refreshed. You do have to write a content provider but personally I think it's worth it. I just realised how complicated all of this sounds, but it is actually so much simpler than jamming everything in your activity classes, which is just crazy but very common to see. I think it's a major failing of Android (as opposed to iOS or windows phone, or maybe most other application platforms!?) that it seems to have been designed with no thought about the absolutely fundamental issue of how you should separate models from views or how you might test your code. http://en.wikipedia.org/wiki/Observer_pattern http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at
[android-developers] Re: INSTALL_FAILED_DUPLICATE_PERMISSION
uses-permission and permission have to be unique On Wednesday, February 18, 2015 at 10:27:03 AM UTC-5, marten wrote: Hi all, we've some problems with Android 5. There seems to be a new policy that requires two apps that define the same permissions to be signed by the same key. Otherwise you can't install the app getting the error INSTALL_FAILED_DUPLICATE_PERMISSION. This is very annoying and I'd like to know that the suggested solution/workaround to this is. We have an Open Source task app that provides access to the tasks via a ContentProvider. The concept pretty much equals the CalendarProvider. We also have a (not yet Open Source) sync app that can sync to this task app (or its ContentProvider). The problem is that (in contrast to the CalendarProvider) our users usually install the sync app first. That means the permissions of the task app are not known when the sync app is installed. So they are not granted automatically when the task app is installed afterwards. Until Android 5 the solution was to define the same permissions in the sync app. But that doesn't work any more in some cases. If the user compiles the task app himself he can not use our sync app at the same time, because they are not signed by the same key. How can we achieve that we protect access to the task ContentProvider by permissions still allowing them to use a self compiled version? Even if both apps are signed by the same key it doesn't seem to work in some cases (does Android 5 also require both apps to be from the same source?) A similar issue exists when another developer tries to build a sync app that can sync to our task app. He can not add the same permissions, because he can't use the same signing key. But if he can't add the same permission definition his app won't get the permission if it's installed before the task app is installed. What's the solution of this mess? thanks Marten -- Marten Gajda Schandauer Straße 34 01309 Dresden Germany tel: +49 177 4427167 email: mar...@dmfs.org javascript: twitter: twitter.com/dmfs_org VAT Reg. No.: DE269072391 -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [android-developers] Re: Which pattern is most common for apps that involve communication with servers?
For me, all network activity is performed by tasks which are executed by executors on a pool of threads. Not Java executors, but something a bit more flexible for my needs -- priorities, cancellation, per-thread affinity based on each task's account, etc. The data is written to a database, served up by a content provider (most of the time anyway, when I need simple automatic cursor-based re-query). -- K 2015-02-21 2:10 GMT+03:00 Kristopher Micinski krismicin...@gmail.com: The main hypothesis I'm wondering about is how developers pass data from their app to the network. Since any use of the network necessarily involves threads, there are a variety of ways this could occur. Most of the ways with which I'm familiar utilize methods where the communication between the app and the network happen with something pretty straightforward. (As an example, in Volley, the threads are somewhat hidden in the request order, and you build up request objects to send to them.) The thing I *don't* want to see is a lot of use of shared variable concurrency to coordinate stuff with a `Thread` instance that is passed to the network, but it doesn't seem like that pops up all that often. Kris On Fri, Feb 20, 2015 at 1:21 PM, erdo e...@ixpocket.com wrote: Sorry for the huge post, but for what it's worth, every app that I do nowadays has the same general pattern... I basically have a model class(es) that incorporates any logic or data that you don't want cluttering up your views/activities/fragments and where you would do any networking stuff. By model I mean the M in MVC or the M in MVVM or the VM in MVVM. (Let's say an account object) You can inject this model class into your views/activities/fragments when you need it - using dagger or you can just roll your own dependency injection code via the application class. That means that the fragment/activity classes just manage their lifecycle and get references to whatever models they need (an account object, maybe a network state object or whatever) and do as little else as possible. When you update the UI, you just run a syncView() method on the fragment or your custom view class (my preference, as it removes even more code from the fragment) that sets the state of all the UI components eg: textView.setText(account.getAccountName()); you just need to make sure all the get() methods on your models return immediately. Any network connectivity or other stuff that needs to be done on a separate thread, I would do from the model class which mostly exists independently of any activity/fragment lifecycle (saving you a whole heap of lifecycle trouble). Once the network stuff has returned with data or an error to the model class, I use the Observer pattern so that the views/activities/fragments or other models that are interested, get notified of the change to the model and then update themselves based on the model's new data (see the syncView() method above). You can roll your own simple observer classes (my preference) or use something like RxJava or even Otto can be used this way. Also if you send all your update notifications on the UI thread, you'll save yourself some headaches when updating UIs based on them. So the models themselves will make use of Volley or Retrofit/OKHttp (both are pretty good and I would definitely use one of them) and may have AsyncTasks in there too. You just have to make sure (especially when using AsyncTasks) that you can independently test the models which means being able to inject the networking stuff (substituting mocked versions for tests). The way AsyncTask is designed makes it particularly awkward to test. You can: Write complicated tests to handle the threading problems using a latch and so on; Test only using a framework like espresso (but then you will be testing via the UI and not strictly doing a unit test; Or you can wrap AsyncTask in your own class that can be used in a synchronous way for tests - that's what I do and it makes the tests much simpler. If you're fetching lists of stuff, I'd use the model classes to write straight to a database once the data has been fetched from the network. ContentLoaders while they do clutter up your fragment/activity code, do seem nice and performant and have a built in observer style mechanism so when the data in your database changes, your view gets immediately refreshed. You do have to write a content provider but personally I think it's worth it. I just realised how complicated all of this sounds, but it is actually so much simpler than jamming everything in your activity classes, which is just crazy but very common to see. I think it's a major failing of Android (as opposed to iOS or windows phone, or maybe most other application platforms!?) that it seems to have been designed with no thought about the absolutely fundamental issue of how
Re: [android-developers] Re: Which pattern is most common for apps that involve communication with servers?
Right, the way I understand it is that this (task based model) is the pervasive for Android development. I would suspect that the only people not using this model are those that are incorrectly using raw threads because they haven't picked up on the right Android facilities. (I'm sure there are cases where Java's threading primitives might have some performance benefit, but I think for the case of most apps, it's more important to have something easy to reason about than hyper-optimized network throughout.) Kris On Fri, Feb 20, 2015 at 6:26 PM, Kostya Vasilyev kmans...@gmail.com wrote: For me, all network activity is performed by tasks which are executed by executors on a pool of threads. Not Java executors, but something a bit more flexible for my needs -- priorities, cancellation, per-thread affinity based on each task's account, etc. The data is written to a database, served up by a content provider (most of the time anyway, when I need simple automatic cursor-based re-query). -- K 2015-02-21 2:10 GMT+03:00 Kristopher Micinski krismicin...@gmail.com: The main hypothesis I'm wondering about is how developers pass data from their app to the network. Since any use of the network necessarily involves threads, there are a variety of ways this could occur. Most of the ways with which I'm familiar utilize methods where the communication between the app and the network happen with something pretty straightforward. (As an example, in Volley, the threads are somewhat hidden in the request order, and you build up request objects to send to them.) The thing I *don't* want to see is a lot of use of shared variable concurrency to coordinate stuff with a `Thread` instance that is passed to the network, but it doesn't seem like that pops up all that often. Kris On Fri, Feb 20, 2015 at 1:21 PM, erdo e...@ixpocket.com wrote: Sorry for the huge post, but for what it's worth, every app that I do nowadays has the same general pattern... I basically have a model class(es) that incorporates any logic or data that you don't want cluttering up your views/activities/fragments and where you would do any networking stuff. By model I mean the M in MVC or the M in MVVM or the VM in MVVM. (Let's say an account object) You can inject this model class into your views/activities/fragments when you need it - using dagger or you can just roll your own dependency injection code via the application class. That means that the fragment/activity classes just manage their lifecycle and get references to whatever models they need (an account object, maybe a network state object or whatever) and do as little else as possible. When you update the UI, you just run a syncView() method on the fragment or your custom view class (my preference, as it removes even more code from the fragment) that sets the state of all the UI components eg: textView.setText(account.getAccountName()); you just need to make sure all the get() methods on your models return immediately. Any network connectivity or other stuff that needs to be done on a separate thread, I would do from the model class which mostly exists independently of any activity/fragment lifecycle (saving you a whole heap of lifecycle trouble). Once the network stuff has returned with data or an error to the model class, I use the Observer pattern so that the views/activities/fragments or other models that are interested, get notified of the change to the model and then update themselves based on the model's new data (see the syncView() method above). You can roll your own simple observer classes (my preference) or use something like RxJava or even Otto can be used this way. Also if you send all your update notifications on the UI thread, you'll save yourself some headaches when updating UIs based on them. So the models themselves will make use of Volley or Retrofit/OKHttp (both are pretty good and I would definitely use one of them) and may have AsyncTasks in there too. You just have to make sure (especially when using AsyncTasks) that you can independently test the models which means being able to inject the networking stuff (substituting mocked versions for tests). The way AsyncTask is designed makes it particularly awkward to test. You can: Write complicated tests to handle the threading problems using a latch and so on; Test only using a framework like espresso (but then you will be testing via the UI and not strictly doing a unit test; Or you can wrap AsyncTask in your own class that can be used in a synchronous way for tests - that's what I do and it makes the tests much simpler. If you're fetching lists of stuff, I'd use the model classes to write straight to a database once the data has been fetched from the network. ContentLoaders while they do clutter up your fragment/activity code, do seem nice and
Re: [android-developers] Re: NullPointerException in java.io.File.fixSlashes?
Good analysis and reasoning. It leads to identifying a specific version of the OS. Let me add to the reasoning: If this was a bug in android-2.3.4_r1, wouldn't many other apps that call the same function also trigger this bug? Then the history would show a 2.3.4_r2 release with this bug fixed. I am guessing that since that may not be the history, then other app developers have found a way to avoid this bug. You need to find that method and add it to your code. The problem may be that the specific stack trace you're looking at is showing where the problem is triggered, but it is not showing where the problem gets set up. Maybe android-2.3.4_r1 is the only OS version which allows a null string to be returned from a certain function call that you're making. Your code might rely on that string always being non-null, and passes it into this call stack. The other OS versions don't have the problem because they don't have the conditions that produce a null string. Your code could test that string for null, and avoid making the call if it is. If you must make the function call, you could replace the null string with something else that won't cause the error. Emit a message, so you can track the problem. Enhance the later code to continue gracefully if the string was found to be null. This is defensive programming. You're right in thinking it should not be necessary, but you must also consider the reality that it is. -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [android-developers] Which pattern is most common for apps that involve communication with servers?
Agreed, thanks for the heads up! Kris On Fri, Feb 20, 2015 at 6:21 AM, Kostya Vasilyev kmans...@gmail.com wrote: You know, I don't. My apps aren't open source, and I came up with it myself, not borrowed from a library. But it's not rocket science, I'm sure you understand the pattern. -- K On Friday, February 20, 2015 at 4:39:32 AM UTC+3, Kristopher Micinski wrote: I agree, that sounds like a useful pattern. I *think* that's relatively close to how Volley is implemented (though I haven't read the implementation fully), too. Do you have any pointers to open sourced code that would provide an example of such a behavior? If not, no big deal: I can certainly write one myself, and am not asking you to open-source code from your codebase. Kris On Thu, Feb 19, 2015 at 4:17 PM, Kostya Vasilyev kman...@gmail.com wrote: A service turned inside out A mediator class that manages a pool of threads, submits / cancels / executes task objects, manages the wake lock (based on having tasks). And a service whose only responsibility is to do startForeground / stopForeground when it's told to. All in the same process. This way I don't have to bind to a service (which is asynchronous) and it's easier to manage state in the UI, to indicate to the user what the app is doing, and to queue up tasks when necessary. -- K -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[android-developers] Re: Which pattern is most common for apps that involve communication with servers?
Sorry for the huge post, but for what it's worth, every app that I do nowadays has the same general pattern... I basically have a model class(es) that incorporates any logic or data that you don't want cluttering up your views/activities/fragments and where you would do any networking stuff. By model I mean the M in MVC or the M in MVVM or the VM in MVVM. (Let's say an account object) You can inject this model class into your views/activities/fragments when you need it - using dagger or you can just roll your own dependency injection code via the application class. That means that the fragment/activity classes just manage their lifecycle and get references to whatever models they need (an account object, maybe a network state object or whatever) and do as little else as possible. When you update the UI, you just run a syncView() method on the fragment or your custom view class (my preference, as it removes even more code from the fragment) that sets the state of all the UI components eg: textView.setText(account.getAccountName()); you just need to make sure all the get() methods on your models return immediately. Any network connectivity or other stuff that needs to be done on a separate thread, I would do from the model class which mostly exists independently of any activity/fragment lifecycle (saving you a whole heap of lifecycle trouble). Once the network stuff has returned with data or an error to the model class, I use the Observer pattern so that the views/activities/fragments or other models that are interested, get notified of the change to the model and then update themselves based on the model's new data (see the syncView() method above). You can roll your own simple observer classes (my preference) or use something like RxJava or even Otto can be used this way. Also if you send all your update notifications on the UI thread, you'll save yourself some headaches when updating UIs based on them. So the models themselves will make use of Volley or Retrofit/OKHttp (both are pretty good and I would definitely use one of them) and may have AsyncTasks in there too. You just have to make sure (especially when using AsyncTasks) that you can independently test the models which means being able to inject the networking stuff (substituting mocked versions for tests). The way AsyncTask is designed makes it particularly awkward to test. You can: Write complicated tests to handle the threading problems using a latch and so on; Test only using a framework like espresso (but then you will be testing via the UI and not strictly doing a unit test; Or you can wrap AsyncTask in your own class that can be used in a synchronous way for tests - that's what I do and it makes the tests much simpler. If you're fetching lists of stuff, I'd use the model classes to write straight to a database once the data has been fetched from the network. ContentLoaders while they do clutter up your fragment/activity code, do seem nice and performant and have a built in observer style mechanism so when the data in your database changes, your view gets immediately refreshed. You do have to write a content provider but personally I think it's worth it. I just realised how complicated all of this sounds, but it is actually so much simpler than jamming everything in your activity classes, which is just crazy but very common to see. I think it's a major failing of Android (as opposed to iOS or windows phone, or maybe most other application platforms!?) that it seems to have been designed with no thought about the absolutely fundamental issue of how you should separate models from views or how you might test your code. http://en.wikipedia.org/wiki/Observer_pattern http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups Android Developers group. To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.