|
Wait, where is the EditText? (Also, tip: use the tools namespace for dummy data, e.g. tools:text=@string/whatever, this will be used in the IDE layout preview but not in the app itself so you don't risk accidentally showing "Hello world" to the user.)
|
# ? Mar 4, 2015 13:33 |
|
|
# ? May 14, 2024 06:25 |
Sorry, it turns out that the xml layout is not used at all. It's all dynamically generated in code. Most of this was written by someone else, so I'm only just figuring out how everything works myself. I suppose all sorts of things can go wrong in this process, so I'll just have to debug some more. I just wish I knew what was different in Lollipop.
|
|
# ? Mar 4, 2015 15:13 |
Look, the text was hiding right above the green line all along! It turns out that the height of the EditText was set to getMinimumRequiredHeight(). This used to take the size of the text into account, but apparently doesn't on Lollipop, so the EditText would just be a thin line. Maybe this is because the EditText is empty at the time it is sized? I've fixed it for now by hardcoding a minimum height, but that's obviously not ideal. Is there a better way to programmatically determine the appropriate height of an EditText? This still doesn't explain why the OnKeyDown is never called, though. Googling around, I've found a couple of people saying that OnKeyDown is unreliable for soft keyboards and to use a TextWatcher instead. I've attached a TextWatcher to the EditText and it works! Now I can get everything working, but I would still like to know why OnKeyDown suddenly stops working on Lollipop. Does the Lollipop keyboard work in a different way than previous keyboards? Should you really just never rely on KeyDown/Up events when using soft keyboards? SimonChris fucked around with this message at 11:11 on Mar 6, 2015 |
|
# ? Mar 6, 2015 11:02 |
|
SimonChris posted:Look, the text was hiding right above the green line all along! It turns out that the height of the EditText was set to getMinimumRequiredHeight(). This used to take the size of the text into account, but apparently doesn't on Lollipop, so the EditText would just be a thin line. Maybe this is because the EditText is empty at the time it is sized? quote:I've fixed it for now by hardcoding a minimum height, but that's obviously not ideal. Is there a better way to programmatically determine the appropriate height of an EditText? quote:This still doesn't explain why the OnKeyDown is never called, though. Googling around, I've found a couple of people saying that OnKeyDown is unreliable for soft keyboards and to use a TextWatcher instead. I've attached a TextWatcher to the EditText and it works! Tunga fucked around with this message at 14:29 on Mar 6, 2015 |
# ? Mar 6, 2015 11:37 |
|
SimonChris posted:
Lets say that I have a soft keyboard that corrects my spelling automatically. I type "Anroid<space>" and the word is autocorrected to "Android". What series of onKeyWhatever events do I expect to have occurred?
|
# ? Mar 6, 2015 14:22 |
Volmarias posted:Lets say that I have a soft keyboard that corrects my spelling automatically. I type "Anroid<space>" and the word is autocorrected to "Android". What series of onKeyWhatever events do I expect to have occurred? Well, I was only using OnKeyDown to listen for the enter key, after which the text would be retrieved with a call to getText(). I'm not trying to parse the input one keypress at a time or anything like that. Pre-Lollipop, every keypress would trigger an event and I would watch for the enter key event. Post-Lollipop the event handler is never called at all, no matter what keys are pressed. I can get around it with the TextWatcher, but I would still like to understand how EditText event handling has apparently changed.
|
|
# ? Mar 7, 2015 10:56 |
|
SimonChris posted:Well, I was only using OnKeyDown to listen for the enter key, after which the text would be retrieved with a call to getText(). I'm not trying to parse the input one keypress at a time or anything like that. Pre-Lollipop, every keypress would trigger an event and I would watch for the enter key event. Post-Lollipop the event handler is never called at all, no matter what keys are pressed. I can get around it with the TextWatcher, but I would still like to understand how EditText event handling has apparently changed. Pull the AOSP source and delta EditText between K and L. You should probably consider setting the imeOptions flag so that the Done button actually does something, instead of listening for the enter key.
|
# ? Mar 8, 2015 02:32 |
|
Volmarias posted:Pull the AOSP source and delta EditText between K and L. Or if you're feeling lazy and you're not a bad enough dude to be pulling AOSP look up the files on grepcode. To be fair soft key event listening is clear as dirt to an Android newbie. Unrelated, but to this day it still bugs me that there's no non-hacky soft keyboard visibility listener. I always get about 3/4 through a project thinking it won't become an issue when some designer decides the screen needs to totally change layouts (w/ animated in between states of course!) based on soft keyboard visibility. speng31b fucked around with this message at 05:41 on Mar 13, 2015 |
# ? Mar 13, 2015 05:35 |
|
speng31b posted:I always get about 3/4 through a project thinking it won't become an issue when some designer decides the screen needs to totally change layouts (w/ animated in between states of course!) based on soft keyboard visibility.
|
# ? Mar 13, 2015 09:00 |
|
Has anybody here had success getting libpd/pd-android up and running in Android Studio? I found this: http://www.journal.deviantdev.com/update-using-libpd-with-android-studio/ but I can't get the dependency stuff set up properly, and trying to build with gradle from the command line fails with :code:
|
# ? Mar 15, 2015 17:02 |
|
Let me preface by saying that I'm working on learning Android (and subsequently Java as well) so keep this in mind if I'm doing something incredibly unorthodox. e: ps I'm sure my naming conventions are dumb and wrong and feel free to mock them. What's the best way to start a loop without locking the UI thread? Background: I'm working on a rock paper scissors game that when you click the start button a timer starts and the computer's choice is displayed. You have x seconds to make the right choice before the image disappears and you lose. If you make the winning choice, the computer presents a new choice and the timer is reduced. This happens until you tie / lose and the game is over. I want the loop to continue as long as the number of losses is still equal to 0 (code is here http://pastebin.com/jvnYwzDW) I coded this all into a while loop that was under my main activity only to find that nothing happened and the app didn't respond. After a bit of research I figured out that the UI thread can't (won't?) update and I think that I need to implement a handler or an async task to do the work but I'm having a hard time wrapping my head around either of these options (and have failed to implement them a few times now). How can I repetitively call gamestart() without showing my start button again until the user loses? It works just fine but I'd like it to repeat and go faster until the user loses. Why does the UI thread lock if there's a while loop going on that consists of a bunch of different UI changes? e: just realized that I still have a start button setvisiblity in my onclicklisteners, ignore that. Mr Newsman fucked around with this message at 19:07 on Mar 23, 2015 |
# ? Mar 23, 2015 18:57 |
|
Mr Newsman posted:Let me preface by saying that I'm working on learning Android (and subsequently Java as well) so keep this in mind if I'm doing something incredibly unorthodox. The problem, as you discovered, is that you were blocking the thread that's responsible for actually drawing and otherwise updating the UI. You're on the right track, though there's a few android-specific things to note, without touching on the general CS design issues here: 1) Your UI elements, such as your buttons etc should generally live in your Activity or Fragment's class as member variables, and be set after you've inflated the layout. This way, you don't have to keep getting references to them. 2) You're creating onClickListeners for multiple buttons with just about the same code; the only real difference seems to be what argument you're passing to mGameplay.setChoice. Since you're given a reference to the View that was clicked, I'd recommend determining the value to pass setChoice by comparing the view that you were passed to the buttons you're expecting, e.g. code:
|
# ? Mar 23, 2015 22:11 |
|
Mr Newsman posted:Why does the UI thread lock if there's a while loop going on that consists of a bunch of different UI changes? A thread is basically the computer executing code line by line, one after the other. Updating the UI and responding to touches and so on, they're all bits of code that the thread needs to execute, ideally as quickly as possible so the user can see an immediate response. But if you're doing some long while loop in that thread, that's code that the thread needs to finish before it can move on to handling view updates and touch handling. The thread is busy running the loop, so all the UI stuff is delayed. (And if it's deferred for too long, you'll get an Application Not Responding popup, which you really don't want people seeing) So the answer is to do as little as possible on the UI thread, so it's free to deal with the stuff it really needs to handle. You can get away with minor things, but anything that's likely to cause noticeable delays should be done on another thread. This other thread executes its code separately, so while that's busy with all the code it needs to get through, your UI thread has very little to do, so it's always ready to handle its business. If you like you can think of the UI thread as being like a secretary - if you give them a lot of extra tasks to do, they might not be able to answer the phone or deal with visitors promptly. If you bring in someone else to handle those tasks, they can just get on with them and let the secretary have the results when they're ready AsyncTask is probably your best bet, I think - for ease of use anyway, since it handles a lot of stuff automatically. Here's the example from the docs: Java code:
Java code:
Hopefully you can work out how to shoehorn your business into that setup. You can roll your own implementations, with a bit more freedom, but this one handles a lot of the boilerplate and messaging issues. It's good for handing off some work that you know will hold up your UI thread baka kaba fucked around with this message at 00:40 on Mar 24, 2015 |
# ? Mar 24, 2015 00:32 |
|
Volmarias posted:
I'd also personally use an enum to store the values for Rock etc. so you don't get them mixed up somewhere and end up with a silly bug. Tunga fucked around with this message at 00:53 on Mar 24, 2015 |
# ? Mar 24, 2015 00:50 |
|
Tunga posted:You can set these "choice" values as a tag on the respective views (just hardcode in the XML in this case) and use them directly (except for parsing back to an int, obviously). No ugly if else else else needed. Absolutely true, and probably a better solution on both counts.
|
# ? Mar 24, 2015 05:12 |
|
baka kaba posted:A thread is basically the computer executing code line by line, one after the other. Updating the UI and responding to touches and so on, they're all bits of code that the thread needs to execute, ideally as quickly as possible so the user can see an immediate response. I'm not sure for a Java/Android beginner that I'd even go so far as to deal with AsyncTask, and it's also not the best choice for this application. AsyncTask is pretty dumb to be honest. There's some weirdness going on like it being a triple-parameterized type (one of the only examples of a scary parameterized type that Android really forces you to use, and it's about the most convoluted example you can get - capital V Void is the worst!). Also it's only a really light abstraction around Java threads, so it's easy to shoot yourself in the foot by writing non-thread-safe code in an AsyncTask if you try to modify the boilerplate without full understanding and access something that didn't come through your parameters in doInBackground and create an unpredictable thready bug that a newbie wouldn't understand (and really shouldn't have to, at that point in their learning). I get Android candidates sending in code all the time with the most egregious AsyncTask threading mistakes because AsyncTask provides the illusion that it's a safe alternative to threading when it's not that at all, it's just a small wrapper. If you don't understand threads and/or don't know where the wrapping happens it's a disaster. Honestly I'd just make a UI thread handler post a runnable that keeps posting itself til it's done. This keeps all your logic on the UI thread. No foot-shooting, period. Also the UI thread is plenty fast enough for the purpose we're talking about here and there's no advantage to using a thread since you're not doing heavy processing that needs to run in a tight loop and you're not calling blocking IO on sockets like networking or whatever, you really just want to check a condition every tick. What we're talking about here is not actually the use case for an AsyncTask at all. A simpler approach would look something like: code:
Oh, and check out the source code for AsyncTask sometime - particularly how its threading model works under the hood - how many times that model has changed over different Android versions and how silly it is even now. If you do make heavy use of AsyncTask for all your background stuff, you should definitely be providing your own Executor, profiling thread pool sizes, etc. The default implementation isn't much more than a toy, it doesn't scale. speng31b fucked around with this message at 06:55 on Mar 24, 2015 |
# ? Mar 24, 2015 06:02 |
|
I can't say I'm an expert on this at all, so I'll definitely defer to you on that one I literally wrote a threaded task not long after that, where the main thread just keeps an eye on a status flag on every frame, I just thought AsyncTask might be the best general option as an introduction since it Generally Works for most 'get that off the UI thread' tasks a newbie might run into, like doing IO. But yeah, if that's real bad advice then call me out, I'm still feeling my way around this area too So your version there is basically throwing the same runnable back into the message queue until it's run out of tasks to do, right? Do one thing and then send it back? That's a nice (maybe embarrassingly entry-level) technique I'll have to remember
|
# ? Mar 24, 2015 10:05 |
|
Awesome. I implemented the handler and included handler.postdelayed and it works like a charm. I have a bug where if you lose or let the timer run out the handler will still post one more game and then stop even though my condition is that the loss clause has to equal 0. I think it's because I have my countdown timer and the postdelayed function of my handler sharing the same variable so the post delayed function is firing before the countdown timer hits 0 and updates the losses variable. e: hurr post delayed means it's posted to run delayed from then. Other than that bug though the framework is all laid out. If I have time to kill at work today I'll work on debugging it and implementing a better solution. As well as cleaner button detection, enums, and just general cleaning up of the code. Thanks for the advice and the great writeups. Sometimes reading the documentation is a bit overwhelming when you're just getting started. e: Got the code working the way I needed it to. Looks like everything works fine, now it's just to rewrite everything to be more clean / concise. code:
Mr Newsman fucked around with this message at 17:26 on Mar 24, 2015 |
# ? Mar 24, 2015 14:25 |
|
baka kaba posted:I can't say I'm an expert on this at all, so I'll definitely defer to you on that one I literally wrote a threaded task not long after that, where the main thread just keeps an eye on a status flag on every frame, This is why you have to be careful with threaded stuff like AsyncTask. Did you remember to make the flag volatile or use AtomicBoolean or synchronize around access to the flag? If not, it'll probably "mostly" work, but there's a subtle bug. baka kaba posted:I just thought AsyncTask might be the best general option as an introduction since it Generally Works for most 'get that off the UI thread' tasks a newbie might run into, like doing IO. But yeah, if that's real bad advice then call me out, I'm still feeling my way around this area too AsyncTask or threading in general is only necessary if a single chunk of operations you perform atomically would be enough to slow down the UI thread. Usually that's only the case with heavyweight operations like image processing or blocking I/O in networking, file system access, database access, etc. Never touch disk or network on the UI thread is a pretty good rule of thumb - it's the reason it's an unchecked exception to try this unless you disable the check - but it's also a pretty good rule of thumb that you should be using someone else's well-tested and robust library to do any of those things rather than spinning up AsyncTasks and manually looping over byte streams (unless your actual project is to create a library for one of these things, in which case, you shouldn't need any of this advice because you know it all already). speng31b fucked around with this message at 19:51 on Mar 24, 2015 |
# ? Mar 24, 2015 19:48 |
|
speng31b posted:This is why you have to be careful with threaded stuff like AsyncTask. Did you remember to make the flag volatile or use AtomicBoolean or synchronize around access to the flag? If not, it'll probably "mostly" work, but there's a subtle bug. Right now there's a state check, when the main thread hits a certain state it creates a thread with a runnable that performs some heavy lifting. Then the main thread keeps checking a 'done' flag, which the runnable sets at the end of its code. I haven't set anything as volatile or synchronized yet, what's the bug? Something to do with out of order execution, or a long delay in the main thread seeing the new value? speng31b posted:AsyncTask or threading in general is only necessary if a single chunk of operations you perform atomically would be enough to slow down the UI thread. Usually that's only the case with heavyweight operations like image processing or blocking I/O in networking, file system access, database access, etc. Never touch disk or network on the UI thread is a pretty good rule of thumb - it's the reason it's an unchecked exception to try this unless you disable the check - but it's also a pretty good rule of thumb that you should be using someone else's well-tested and robust library to do any of those things rather than spinning up AsyncTasks and manually looping over byte streams (unless your actual project is to create a library for one of these things, in which case, you shouldn't need any of this advice because you know it all already). Haha well, I thought AsyncTask was someone's well-tested and robust library since it's part of the framework and they recommend it as a way to offload work without worrying about Handlers and the like. I mean this isn't exactly new, the docs don't exactly feel... cohesive, sometimes the information you're looking for is spread over multiple pages in multiple sections, and it doesn't always feel like it's pushing the same concepts. What do you mean about looping over byte streams though? I thought the whole idea of AsyncTask (whether it's the actual reality or not) was to provide a simple way to box up and offload work to another thread, let the main thread know when it's done, and take care of all the multithreading issues for you? This is assuming your worker task isn't interacting with things the main thread is interacting with of course. I realise this sounds incredibly naive - I've read through the SMP primer page but I still haven't fully absorbed it and all the options available. Actually while we're on this and there's some action in the thread, I have a question! Say you're polling and analysing some sensor data, with a bunch of processing, and another thread needs to read the most recent data values - how would you coordinate that? Would you keep a set of public variables somewhere, and perform synchronized groups of read and write operations on them? Or would you have the sensor thread keep all the values private, and have some kind of messaging setup where the other thread sends update requests and receives a set of data back? (Stop me if any of this sounds stupid, I'm really new to having to worry about any of this)
|
# ? Mar 25, 2015 10:52 |
|
baka kaba posted:Haha well, I thought AsyncTask was someone's well-tested and robust library since it's part of the framework and they recommend it as a way to offload work without worrying about Handlers and the like. baka kaba posted:What do you mean about looping over byte streams though? baka kaba posted:Actually while we're on this and there's some action in the thread, I have a question! Say you're polling and analysing some sensor data, with a bunch of processing, and another thread needs to read the most recent data values - how would you coordinate that? If you need to store a lot of historic data and provide arbitrary access to that then I'd probably look at throwing it all into a SQLite or something and having other threads read from that directly. As long as the Service writes and everything else reads you shouldn't hit any disasters. I may not have put enough thought into this though. Tunga fucked around with this message at 11:45 on Mar 25, 2015 |
# ? Mar 25, 2015 11:34 |
|
If you haven't yet, read the Oracle java tutorials. The ones about multi threading will help answer a lot of your questions.
|
# ? Mar 25, 2015 12:22 |
|
^^^ I have and they're excellent, but I didn't read the multithreading stuff too closely at the time. I'll definitely get back to thoseTunga posted:I have to say that I've never really run into any problems with AsyncTasks but I've only really used them for fairly trivial stuff. Partly because... Oh yeah, I was just wondering if speng was talking about a specific use case instead of running some arbitrary code off the main thread. I'm actually terrible about not using libraries, I think I need to do a mini project where I cobble something together using them as much as possible, just to get used to the idea of plugging in functionality instead of writing it myself. (Speaking of which, have you seen that Snackbar alert/dialog in Material Design? It's a standardised popup, except there's no API for it, they just say 'make it look like this' and you're supposed to code it yourself. I hate to ask but is this... normal with Android? Cripes) Tunga posted:I've never done much with sensors but I would probably run the sensor monitoring code as a service and then have the app bind to it when it needs to retrieve data. This makes it easy to have the sensor stuff always running while you're switching activities (or apps, if that is needed) and provides an easy way to do the cross-thread communication. The exact way you store the data isn't too important, if you're only ever returning the latest sensor value then just throw it in a private field and put a getData() on the service to return that value. The sensor stuff is receiving events and calculating constantly, but it only runs while the app is visible (while a surfaceview is rendering actually), and the reader is getting updates every frame, which is why I'm not sure if a service is the best fit? Does it create a lot of overhead? Right now I've just got the processor's onSensorChanged method doing the calculations and writing to a public field, and the reader just looks at them to get the lastest numbers, which is really half-assed but it seems to work ok for now. (There's no historic data, just a bunch of ints and doubles holding the last calculated state) I'm just worried it'll create an issue somewhere, and ideally I'd like to update atomically so the reader isn't getting some old and some new values if it reads at the wrong time. I was thinking of making a synchronized read/write method but I'm not exactly sure it's the right way to go
|
# ? Mar 25, 2015 12:48 |
|
Libraries are one of the best parts about programming! Implement cool, well-tested functionality without all the work of doing it yourself. Go forth and use all the libraries. (replace work of implementing functionality with work of finding appropriate library)
|
# ? Mar 25, 2015 14:27 |
|
Yeah I finally looked at web dev again for a thing I need to do, since my days of handcrafting artisanal HML and CSS files in notepad, and holy moly I wonder if the murderous AI that will eventually kill us all will build itself from GitHub repositories
|
# ? Mar 25, 2015 15:09 |
|
baka kaba posted:Right now there's a state check, when the main thread hits a certain state it creates a thread with a runnable that performs some heavy lifting. Then the main thread keeps checking a 'done' flag, which the runnable sets at the end of its code. I haven't set anything as volatile or synchronized yet, what's the bug? Something to do with out of order execution, or a long delay in the main thread seeing the new value? It's only an issue if one or more threads are checking the state of a non-volatile, non-synchronized value that is updated by another thread over the course of its execution. For instance if one thread "owns" a variable and it updates that variable and other threads "watch" that variable without synchronization or some other explicit thread safety technique, it's a bug. Read over the Oracle docs on threading again as another poster suggested and you'll see what I mean, this is literally the prototype scenario for "what not to do with Java threads" so there's lots of info on it. baka kaba posted:Haha well, I thought AsyncTask was someone's well-tested and robust library since it's part of the framework and they recommend it as a way to offload work without worrying about Handlers and the like. I mean this isn't exactly new, the docs don't exactly feel... cohesive, sometimes the information you're looking for is spread over multiple pages in multiple sections, and it doesn't always feel like it's pushing the same concepts. Yeah based on the docs that is a problematic misconception. It's not really about being well-tested and robust or not - AsyncTask is as well-tested and robust as Java threads are, it just shouldn't be used in situations when you don't just want a slightly more convenient syntax for spinning up a raw thread. In any Java app, Android or otherwise, it would be poor style to spin up unabstracted raw threads for most core tasks. AsyncTasks are still fine for spinning off one-off operations that you couldn't solve with a more centralized solution. For example, in one app I've been working on, we need to generate barcodes from raw QR/barcode data that comes back from a web service. We don't want to generate images on the main thread, but it's also silly to introduce a dependency for something as simple and one-off as generating a scannable Bitmap to stick in an ImageView. So we spin off an AsyncTask for it. That makes sense. Writing your own networking layer held together with the Java equivalent of duct tape and Elmer's glue probably doesn't make sense, though. And that leads to... baka kaba posted:What do you mean about looping over byte streams though? I thought the whole idea of AsyncTask (whether it's the actual reality or not) was to provide a simple way to box up and offload work to another thread, let the main thread know when it's done, and take care of all the multithreading issues for you? This is assuming your worker task isn't interacting with things the main thread is interacting with of course. I realise this sounds incredibly naive - I've read through the SMP primer page but I still haven't fully absorbed it and all the options available. The "looping over byte arrays" comment is more of a benchmark for when it's a good idea to use a library than a hard and fast rule. Generally speaking if you find yourself reading raw bytes streams in an AsyncTask, you should stop and ask yourself if there's a well-known, well-documented, well-tested dependency that will do this for you. The answer is probably yes and it's probably something in one of Square's repos. There's nothing fundamentally wrong with reading byte streams in a thread, but it's just the sort of task a library is well-suited to accomplish because that broader base of usage can account for a lot of issues that you probably wouldn't find yourself until something started failing in production in some weirdly specific range of devices (I'm looking at you, LG devices running 4.1.x). baka kaba posted:Actually while we're on this and there's some action in the thread, I have a question! Say you're polling and analysing some sensor data, with a bunch of processing, and another thread needs to read the most recent data values - how would you coordinate that? Would you keep a set of public variables somewhere, and perform synchronized groups of read and write operations on them? Or would you have the sensor thread keep all the values private, and have some kind of messaging setup where the other thread sends update requests and receives a set of data back? (Stop me if any of this sounds stupid, I'm really new to having to worry about any of this) Depends on how complex the data you need to monitor is. If it's just a boolean or an int or something, and only one thread is allowed to update the data but others are allowed to monitor it, the volatile keyword works well. AtomcXXX classes in java.util.concurrent.atomic package work well. Synchronized getters/setters work well. If you need something a little more robust and are looking for a wholesale solution to eventing tailored for Android I'd recommend looking at Otto from Square (http://square.github.io/otto/), which supports both broadcasting general events and receivers that pull the latest state on demand when they register. Android also provides tons of built-ins for this sort of thing, like Services, though I do think there is a tendency to overuse services for things that there are simpler solutions to. This is a pretty broad problem so there are lots of good answers. speng31b fucked around with this message at 16:15 on Mar 25, 2015 |
# ? Mar 25, 2015 15:58 |
|
baka kaba posted:I'm just worried it'll create an issue somewhere, and ideally I'd like to update atomically so the reader isn't getting some old and some new values if it reads at the wrong time. I was thinking of making a synchronized read/write method but I'm not exactly sure it's the right way to go I've not had an opportunity to use Otto yet but various developer friends have recommended it to me and everything else that I've used from Square has been excellent.
|
# ? Mar 25, 2015 17:51 |
|
speng31b posted:It's only an issue if one or more threads are checking the state of a non-volatile, non-synchronized value that is updated by another thread over the course of its execution. For instance if one thread "owns" a variable and it updates that variable and other threads "watch" that variable without synchronization or some other explicit thread safety technique, it's a bug. Read over the Oracle docs on threading again as another poster suggested and you'll see what I mean, this is literally the prototype scenario for "what not to do with Java threads" so there's lots of info on it. It's more of a lazy technique - thread A sets flag to false and spins off thread B. Then every frame thread A checks the flag. Thread B sets it to true when it's done, eventually thread A sees it and runs the followup code. Intuitively it feels like it would work fine and there might just be a couple of frames' delay before thread A sees the updated flag - is that generally true on Android, or are there weird potential out-of-order issues that could set the flag too early or have thread A see it incredibly late, or even never, without some judicious keyword usage? I'm not saying this is a good idea, or arguing so I can keep doing it (I'm reading up on the Oracle docs now), just trying to get a feel for it if you don't mind speng31b posted:The "looping over byte arrays" comment is more of a benchmark for when it's a good idea to use a library than a hard and fast rule. Generally speaking if you find yourself reading raw bytes streams in an AsyncTask, you should stop and ask yourself if there's a well-known, well-documented, well-tested dependency that will do this for you. The answer is probably yes and it's probably something in one of Square's repos. There's nothing fundamentally wrong with reading byte streams in a thread, but it's just the sort of task a library is well-suited to accomplish because that broader base of usage can account for a lot of issues that you probably wouldn't find yourself until something started failing in production in some weirdly specific range of devices (I'm looking at you, LG devices running 4.1.x). That makes sense, and one of the few places I'm using an AsyncTask is doing... yeah let's just say I've got some byte streams. I need to make that more robust anyway so I'll definitely be looking into some libraries speng31b posted:Depends on how complex the data you need to monitor is. If it's just a boolean or an int or something, and only one thread is allowed to update the data but others are allowed to monitor it, the volatile keyword works well. AtomcXXX classes in java.util.concurrent.atomic package work well. Synchronized getters/setters work well. If you need something a little more robust and are looking for a wholesale solution to eventing tailored for Android I'd recommend looking at Otto from Square (http://square.github.io/otto/), which supports both broadcasting general events and receivers that pull the latest state on demand when they register. Android also provides tons of built-ins for this sort of thing, like Services, though I do think there is a tendency to overuse services for things that there are simpler solutions to. This is a pretty broad problem so there are lots of good answers. Haha this has always been my problem, so many options, and it's not always obvious why you'd prefer one AsyncTask over the other. I guess I'll look at the docs and work out a simple solution to introduce a bit of safety, and then look at the more involved structures to see if there's anything I need. Thanks guys!
|
# ? Mar 26, 2015 08:57 |
|
baka kaba posted:It's more of a lazy technique - thread A sets flag to false and spins off thread B. Then every frame thread A checks the flag. Thread B sets it to true when it's done, eventually thread A sees it and runs the followup code. Intuitively it feels like it would work fine and there might just be a couple of frames' delay before thread A sees the updated flag - is that generally true on Android, or are there weird potential out-of-order issues that could set the flag too early or have thread A see it incredibly late, or even never, without some judicious keyword usage? What you're talking about is called a Condition Variable. I'm not super familiar with Android, but most platforms that allow concurrency also have some type of CV structure that supports signalling waiting threads. You shouldn't see much of a delay at all between your worker thread completing and your primary thread being signaled if you're using the platform's support for it. fake edit: What do you know, Android is kind enough to name their implementation in a non-stupid way: http://developer.android.com/reference/android/os/ConditionVariable.html
|
# ? Mar 26, 2015 15:10 |
|
Actually in this case, I think that's the opposite of what I need! I added the threading to avoid blocking a renderer thread during some initialisation work, so it's just keeping an eye on the progress while it does its thing. Definitely good to know though, thanks - I already did some while loop spinning before I settled on something else, and I can see this being useful in other places too
|
# ? Mar 26, 2015 18:30 |
|
baka kaba posted:It's more of a lazy technique - thread A sets flag to false and spins off thread B. Then every frame thread A checks the flag. Thread B sets it to true when it's done, eventually thread A sees it and runs the followup code. Intuitively it feels like it would work fine and there might just be a couple of frames' delay before thread A sees the updated flag - is that generally true on Android, or are there weird potential out-of-order issues that could set the flag too early or have thread A see it incredibly late, or even never, without some judicious keyword usage? No this is the exact antipattern I'm talking about. Don't do this, you're right about the errors it might cause. Not to be too harsh but if I saw an interview candidate provide code that did this I'd move on. To summarize, a thread modifying a variable is not required to publish the state of that variable to other threads except when synchronization or the volatile keyword are used. Implementations vary, but you can think of each thread as having its own memory space (this is not exactly true, but it's a good way to conceptualize it). It costs resources to publish that memory space to other threads, so when resources are not available, some environments will have threads keeping their updates "secret" unless explicitly flushed. Take a look at this stack overflow answer for a bit more detail: http://stackoverflow.com/questions/2787094/how-to-demonstrate-java-multithreading-visibility-problems Like many threading mistakes, this sort of thing will only manifest as a noticeable bug under specific conditions in specific environments. This is why you don't typically use raw threads if there's a nicer solution available (or raw AsyncTasks, which aren't as far abstracted from threads as some people believe). Java threading is a trap for complacent programmers to make silly mistakes that are very difficult to diagnose even if you're very experienced. Long story short, read the book Java concurrency in practice. You'll be happy you did. speng31b fucked around with this message at 05:36 on Mar 27, 2015 |
# ? Mar 27, 2015 05:28 |
|
Trying to grok rxjava by incorporating it into a side project I'm building here. I'm putting together a streaming radio player. I've got a JSON backend I'm hitting with Retrofit that pulls down information about what's "now playing." The main activity for the app should be getting this info periodically (let's say every 60 seconds), so if you've got the app foregrounded you're seeing a rough approximation of what's on the air. If you're backgrounded and playing music, I want to have the info appear in the notification (presented by a player service) and be updated periodically as well. I'm seeing an example or two that define a singleton class that sets up a BehaviorSubject and periodically post updates at it. Then the individual consumers (i.e. my player service and my activity) can subscribe on this. Since the BehaviorSubject emits the latest-seen item observed, subscribing means you get the last known "now playing" value right away. Is that the best/right way to accomplish what I'm trying to do here?
|
# ? Mar 27, 2015 05:33 |
|
baka kaba posted:(Speaking of which, have you seen that Snackbar alert/dialog in Material Design? It's a standardised popup, except there's no API for it, they just say 'make it look like this' and you're supposed to code it yourself. I hate to ask but is this... normal with Android? Cripes) Well, err, it... yes. Though, I think Google is getting better about it. An upcoming release of AppCompat will finally have some kind of NavigationDrawerView to actually provide a full nav drawer implementation. As for the snackbar, though, GitHub has you covered. Speaking of AppCompat, I ran into https://code.google.com/p/android/issues/detail?id=78377 while finally getting our project at work over to Android Studio and the support libraries. Samsung! kitten smoothie posted:I'm seeing an example or two that define a singleton class that sets up a BehaviorSubject and periodically post updates at it. Then the individual consumers (i.e. my player service and my activity) can subscribe on this. Since the BehaviorSubject emits the latest-seen item observed, subscribing means you get the last known "now playing" value right away. Is that the best/right way to accomplish what I'm trying to do here? To me it sounds like a nicer design would use Otto and its producer functionality which can dispense the "now playing" when any object subscribes. Your objects are more decoupled, then, because they don't need to know about a singleton. They merely subscribe to receive the appropriate object types. I used Guava's EventBus in a project recently and the decoupling was absolutely magical. "Object X needs to receive updates... subscribe! Done." And Otto is even better because of that producer capability, so I highly recommend trying it.
|
# ? Mar 27, 2015 07:57 |
|
Yeah I noticed a few people had made snackbar libraries, I just thought it was hilarious that you've got this big ~Material Design~ push with all these features to make it easier to have a dynamic, material app, and soooo many new APIs in Lollipop and then... this standardised system dialog, described in the design pages, is effectively a bunch of rules about padding. Don't provide an xml file or anything! I love the first reply on that AppCompat thread speng31b posted:No this is the exact antipattern I'm talking about. Don't do this, you're right about the errors it might cause. Not to be too harsh but if I saw an interview candidate provide code that did this I'd move on. No no, harsh away - I wouldn't be asking all these questions if I thought it was safe and the right way to do it. I like to know I'm structuring things properly, so I need to know at least the basics of where the pitfalls are and make sure I'm addressing them somehow. Anyway I'm convinced, this is the next thing I'm fixing and it's about time I got a handle on it, cheers!
|
# ? Mar 27, 2015 12:43 |
|
This is largely for my own sanity, but I'm curious about something. We want to gather touch data for an app and write the type of touch to a database. While we can get the touch type easily enough, I noticed there was a very handy looking function called actionToString() in MotionEvent that translates the touch type directly to a sensible string. For somer reason, any attempt to use it failed; intellisense didn't detect it, manually calling it results in unrecognized error and I can confirm it was indeed there in the source code (its build-in Android stuff). On researching it, it turns out this call is hidden on earlier version of Android SDK (pre 19 I think), despite the fact that literally all it does is perform a switch statement and returns a string with the action type. Does anyone know why the hell this is hidden?
|
# ? Mar 27, 2015 14:19 |
|
PiCroft posted:This is largely for my own sanity, but I'm curious about something. We want to gather touch data for an app and write the type of touch to a database. While we can get the touch type easily enough, I noticed there was a very handy looking function called actionToString() in MotionEvent that translates the touch type directly to a sensible string. For somer reason, any attempt to use it failed; intellisense didn't detect it, manually calling it results in unrecognized error and I can confirm it was indeed there in the source code (its build-in Android stuff). If it's not publicly available, you CANNOT rely on an OEM not loving it up. This has bitten me in the past. If it's public now, you can always git blame the reason from AOSP.
|
# ? Mar 27, 2015 14:59 |
|
I have no idea why it was hidden, maybe it wasn't (thought to be) finished? The code for it is fairly trivial anyway, it is mostly just returning the enum name. It's also static, so just copy that code to a helper method and you should be good.
|
# ? Mar 27, 2015 15:07 |
|
Tunga posted:I have no idea why it was hidden, maybe it wasn't (thought to be) finished? This is what I did anyway, I was just mystified why such a trivial bit of code was hidden at all. Maybe the action enums changed at some point or was due to change? Anyway, mini-rant over.
|
# ? Mar 27, 2015 16:59 |
|
Any idea what would cause emojis to be displayed like this: Might as well be a forum problem I guess.
|
# ? Mar 28, 2015 15:27 |
|
|
# ? May 14, 2024 06:25 |
|
Kinda looks like a stride problem with a bitmap stream, or something? Are they the monochrome emojis?
|
# ? Mar 28, 2015 18:11 |