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 <[email protected]>: > 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 <[email protected]> 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 [email protected] To unsubscribe from this group, send email to [email protected] 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 [email protected]. For more options, visit https://groups.google.com/d/optout.

