Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Fluue posted:

I'm building a simple app that queries my site, gets the json response, then displays data in a view. I'm having trouble grasping how to pass data to a view, though. I'll be taking several fields from each response, and I assume I need to use a listview.

Does anyone have a guide that helped you understand passing data to views?

What kind of data are you displaying? Listviews are meant for lists, and you'll want an adapter to use them properly. Is it sufficient to just have a plain old TextView? If so, then it's as simple as calling setText.

Adbot
ADBOT LOVES YOU

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

TheReverend posted:

Well that fixed it. I had orientation|keyboard before you told me to add in screensize.


That's really the default behavior though? I thought it was pause-resume for screen changes. That seems undesirable. Or is it desirable and I'm not doing stuff right?

Oh well thank you!

It's desirable. Consider the case where you have separate layouts for portrait and for landscape. The safest way to handle this is to recreate the activity and inflate the new layout. If you know you can handle these config changes yourself, you can declare that you do, but you should still be able to recreate your state as appropriate (say the locale changes due to someone's notification's pending intent).

See http://developer.android.com/guide/topics/manifest/activity-element.html#config for more great possibilities to your code barfing.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
As an android developer transitioning to iOS, I can't stress enough that each platform has it's own design patterns and idioms, and it's both easy and annoying for your users to spot a crappy port.

If you can, write for each, not both.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Infomaniac posted:

Any prefered libraries to calculate running pace? Do running apps use info from the maps api or use accelerometer data from the device? How is this tested at home- do you just have to go for a jog or can you set up some tests at home?

I'll be researching this today and just thought I'd start here if anyone had some experience with this sort of thing.

There's two separate things to use; the Location APIs (GPS), and the Motion Sensor APIs (Accelerometer/Linear Accelerometer). There's probably someone's library to help out, but it's a question of whether you want aggregate info about your general pace, distance, etc, or whether you're looking for more of a pedometer.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

mod sassinator posted:

This is dumb, but where do you see the logcat output from a unit test run in IntelliJ? I want to see some stuff being logged during the test run, but when I go to the logcat view after the test run it's not updated. Seems like the logcat view only shows data from actual runs. I have to be missing something obvious--how do you see the logcat from a test run?

edit: Found an option for my test run configuration to clear the logcat before running. Checked this and the logcat is cleared, but there's still nothing being written to it. Wtf, is this a bug of AS?

Possibly.

You can always just do lolcat from the commandline, which has various benefits/drawbacks.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Newf posted:

I posted this in the General Programming thread but didn't get any feedback.

I've got an opportunity to take a piece of Android/iOS contract work doing a "walking tour" app. The idea is to have the app use the phone's GPS to place the user on a map as they tour a city, show videos at specific locations, and return to the map screen after the videos play out or the people leave the area.

This seems fairly straightforward to me, but I'm really at a loss for producing an estimate or quote, since I'm new at mobile (and also at producing quotes).

Any thoughts?

There's no great answer to give, because there are a lot of variables here.

- How long do you realistically expect this to take? Have you done anything like this before?
- How will you be showing the videos? Will you just be opening YouTube at the appropriate time, or is your app going to handle this? Streaming video can be surprisingly non-trivial if you want it to be robust.
- What kind of experience do you have? Do you have other applications published, that you can refer to as prior experience?
- How will you be displaying the map? As an aside, if you're going to use the Google Maps interface, it's only free as long as the app is non-commercial if I recall. If the app owner will be selling it, they'll have to negotiate a rate. You should not pay this if you are not the owner.
- How much effort are you going to actually put into this looking good? Are you going to hard-lock this to portrait and say "Eh, good enough" and test against a couple devices, or do you plan on trying to make this a good experience for all users on all form factors?

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Uncomfortable Gaze posted:

Maybe, but painful nonetheless.

You really need to be careful committing to two completely different platforms, especially if you have little experience in either. ObjC is a reasonably modern C, but it can be pretty jarring coming from a java/c# background. Android uses pretty modern Java as well, in that you aren't hamstrung by a lot of the java 1.4 era stuff you see in other Java-based platforms. You'll probably have a much easier time with the Android app, but don't discount the fact you'll still need to learn quite a lot to get to a finished product. That price estimate might work for just Android, albeit still low, but doing both platforms for that price is really questionable.

Loading videos in the background as they go around sounds like a good compromise. If this is intended for a specific museum, then they can provide wifi to make this easier for users. It's a shame that downloads on cellular are still quite painful even in TYOOL2014.

All of this. You actually probably ought to bundle the videos with the app if the expectation is that the user will view all of them, and for a short period. They can use WiFi to download the app and know the cost ahead of time in data.

Don't forget that some people still have data limits, which is why I'd recommend against streaming. The reason I suggested it in the first place is that users on older devices might have limited space available, so streaming allows them to save space.

If you're new to android, your app is going to look awful, mostly because you don't know what to watch out for. You probably aren't used to using fragments, but you'll probably only have one activity anyway so it's probably not a big deal.

I'd strongly recommend finding a video playback library that will give you a nice wrapper around the media player libraries, so that you don't waste a lot of time on that.

Agreeing that you should charge hourly if possible.

Another thing to ask: are you going to work on this full time, or do you have another job or school? If you devote all of your time to this, it might be reasonable to come from zero experience to making something decent on both platforms, but if you can't devote a lot of time you might want to commit to one platform only first. I'd recommend iOS since that's going to be easier to come to grips with multiple form factors and versions until you're used to that.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Newf posted:

Woo. An idea I had isn't bad.


How can I command an hourly rate when somewhere between 1/4 and 3/4s of my time will be spent learning things that mobile professionals already know? Do I compartmentalize my 'learning' and my 'dev' time and bill for 'dev', or bill for everything at a lower rate? Honestly a flat fee makes me less nervous and I hate the idea of bookkeeping overhead. I'm not a fantastic bookkeeper.


I'm currently employed, but it's a fragile situation. If I took up this mobile project, I would ditch my current gig to concentrate on it and learn as much as I can about the field. My current gig is as likely as not to evaporate over the same time frame, so it makes sense to me to take the opportunity to diversify my skill-set and +1 my reference count.

The guy who's offering the mobile project is pretty well connected in my town, and he figures that he already knows of at least one other job that could follow this one. I'm really 'into' the prospect of building myself into a self employed contractor, and I think that this job (for this person) could be a step in that direction... ?

If this falls through and you don't make anything from it, let alone continued employment with this person, will you be able to survive until you get a new job?

If not, I would strongly recommend against doing this until you have more experience and are more established.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Learn the core java concepts first, so that some of android's concepts make sense.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Also, in case it was not clear, mTitle and this.title do not point to the same variable.

The "this" operator is most useful to understand in the context of scoping. E.g.

code:

Public class Foo {
  ...
  // never do this irl
  private Static String bar;
  private String bar;
  ...
  public void bar(String bar) {
    Foo.bar = "Class Variable"
    this.bar = "Member (Instance) Variable"
    bar = "Local Variable"

    System.out.println(Foo.bar + ", " this.bar + ", " bar);
  }
}

If this isn't clear, please study Java until it is before proceeding. This is pretty important.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Karthe posted:

How crazy am I for wanting to try and make a mobile game without using a game library? As in, I just use regular Android like with any other non-game app. I want to make a simple turn-based game, and while most games use Unity or the like, it seems a bit overkill for something as basic as what I have in mind.

Should I just quit bitching and learn to Unity?

If you're going to make a simple game engine and you can represent your game state in standard views, not crazy at all. That said, you may well decide to at a minimum make your own surfaceview implementation, which lends itself towards you writing at least a minimal engine.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
There ARE ways to make your UI always be on top, but it's generally not a good thing for you to do.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Kenishi posted:

However recently when I try to build and run the app in the emulator I'm getting a ton of errors saying it can't find the classes, almost as if they aren't getting exported.

That's because they're probably not. If you use baksmali or something similar on the apk, you'll probably find them missing.

As to why, the answer is usually Because Eclipse. I'm not sure what else to suggest to you without being able to see what your actual project setup is, sorry. It's possible that something weird with maven is going on, where it thinks that it's exporting the artifact but actually isn't.

Also, "Droid" is a Verizon marketing term. The word you are thinking of is "Android" :eng101:

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Android Studio is still very much a beta, but it's better than Eclipse at this point.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Tunga posted:

Like you, I also attended the Terrible School Of Let's Make Them Use Netbeans That'll Be Funny. Sorry about that. You'll get over it, just give it time.

Yeah, I'd go with Android Studio then. The default keybinds are stupid (which is IntelliJ's fault) but other than that there is no particularly compelling reason to favour Eclipse. Google have made it clear that they will continue to support both but it's obvious where their focus lies.

As well as the official ones from Google, I also found Lars Vogel's tutorials useful:
http://www.vogella.com/tutorials/Android/article.html
https://developer.android.com/training/basics/firstapp/index.html

Be careful with the Vogel tutorials, I've found that they can be outdated or outright wrong in some cases.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

kitten smoothie posted:

I'd have them sign up and pay the $25, and add you as an authorized user on their Play Store distributor account so you can upload binaries.

Yeah, I have to agree with this. If this is contract work where you don't own the deliverable, have them deploy under their account. This way, if they stop using you, it's not weird on everyone since they would have to ask you to do deploys.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Kenishi posted:

I'm trying to figure out if the way I'm using this AsyncTask is causing references to be maintained somewhere and causing the thread to not exit/be GCed.

code:

class Foo extends AsyncTask<String, Void, Boolean) {
   private static final Logger = ...;
   private static final int port = 9999;

   protected doInBackground(String...data) {
       boolean result = sendData(data);
       return Boolean.valueOf(result);
   }

   public static boolean sendData(Bar obj) {
        String data = obj.getData();
        return new Foo.execute(data).get().booleanValue();
   }
   
   private static boolean sendData(String data) {
       // Do UDP socket stuff
       // Close socket
       return true;
   }
}

Every time I do the action that causes this to run, a new AsyncTask is made and it runs no problem, but then I see in the debugger that it still has "Running" status. Is that normal or is the static stuff causing problems?

Is this all your async task is doing? If so, just use a threadpool or thread. Async tasks are really more for doing UI before and after in a safer way.

Speaking of which, async tasks are run on a threadpool, so it's probably fine. Pause on one with the debugger if you want to make sure that it's not blocked.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Karthe posted:

Is there a way to force a method's int parameter to be a reference to a Drawable/Style/etc... instead of just a plain ol' integer? I'd like to be able to force an error if I forget to pass in a R.style.style_name when I call the function.

No, I don't think you can parameterize that, unless you want to write a bunch of wrapper classes and transform your codebase :(

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Newf posted:

This is a shameful double post from the Inspect your Gadgets Android thread.


My girlfriend dropped her galaxy ace 2 phone and it's got a crack horizontally through the screen. The touch screen is working above the crack but not below. This has left her unable to unlock the phone.

She has had a couple of missed calls on the phone since, and I'm hoping to figure out how I can get the information behind those missed calls - eg, who called. It's somewhat urgent, since she just started as a substitute teacher, is expecting on-call work, and doesn't want to make bad first impressions of not returning calls.

Suggestions? I'm capable of installing that android port of eclipse or something to that effect if there's an easy bridge for me to access the data, but I've never touched any android programming so I probably won't be able to do anything too fancy.

Any consumer tools for this sort of thing?

Unless she happened to have USB debugging enabled, you are almost certainly out of luck, sorry. If she did, you could probably write something that acquires the screen guard unlock and doesn't release it.

Apps installed via remote purchase still require the user to manually open them first before they accept any other signals.

Edit: your phone company knows who called you, use their website.

Volmarias fucked around with this message at 22:55 on Oct 1, 2014

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Newf posted:

Bleh. Going to buy a new phone at the mall. The phone company has been pretty helpful but unfortunately their own access to the call history only updates every 24 hours. Thanks for the info though :)

No problem. Replacement screens won't be that expensive, stop by the phone repair kiosk your mall almost certainly has and see what they say they can do on short notice.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Sir_Substance posted:

I'm doing some entry level stuff here, and I've stumbled across something I feel should be obvious, but isn't.

I would like to pass an object from one activity to another. However, the putExtra function does not allow the passing of arbitrary objects.

Correct if I'm wrong, but the two most commonly proposed workarounds, implementing seralizable and parcelable, both copy the object. I would like to pass the object itself (it would be a reference to the object if this were c++) so that any changes I make to it in that activity will be available to the rest of the app.

The third most popular alternative seems to be using global variables. Is there no better way of doing this simple thing?

There is not. It is expected that you are passing flat data between activities, because intents are meant to launch activities/services both in process and OUT of process.Naturally, passing java objects between different java processes would be problematic, to say the least. How would you pass your object to the email client, for example?

Using a global store of some kind is definitely the least unreasonable way to do this. Typically, you'll have a map somewhere, and you'll pass a key to that map to reference your object. That said, given that your activity/application can be killed and recreated, usually you'll want your objects to live somewhere more persistent.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Sir_Substance posted:

Well, that's frustrating. It definitely sounds like they took two separate jobs (passing data around within a single app and passing data between apps) and needlessly crushed them together.

Not at all. Intents are not for passing around data, they are for performing actions. While you typically use explicit intents within your own application, it is important to remember that their power lies with implicit intents, where you only state "I wish to view this foo" and you rely upon the most appropriate provider to do so. That provider may be in your application or in another.

If you are using intents solely to pass data around activities, rearchitect your app.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Safe and Secure! posted:

So what's the state of android development tools? Is everything still the biggest pain in the rear end possible? I want to play around with android but I dread spending a day to get a hello world app running on my phone because I have to download a special version of eclipse and then make sure I've got a billion different plugins installed and configured properly.

Pick up Android Studio(beta), which is basically IntelliJ with the Android plugin built in. The build system is built atop gradle now and everything is very sensible. Things have improved over the last several years, I'm not sure what version of Eclipse you tried with last.

Jarl posted:

Having added a runnable to the ui-main-thread using Activity.runOnUiThread(Runnable), View.post(Runnable) or View.postDelayed(Runnable, long) is it then omitted when it's about to be run if the activity has been destroyed?

I assuming not, but I've been unable to get any confirmation. If so I'm considering checking with isFinishing() inside the runnable's run() method.

For Activity.runOnUiThread, it will definitely be pushed to the UI Looper's queue. For View.post(delayed), this appears to happen as well but I can't guarantee that (it should be easy to check though!)

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Tunga posted:

ListViews seem to be unnecessarily complicated. Anyone have a good article explaining the best way to get a bunch of structured data (in my case some JSON) into a ListView with multiple text/image items on each line? I'm guessing I need a custom View which inherits from whatever a ListView displays?

Extend a new BaseAdapter and use a custom view as you suggested. It's pretty straightforward. Just make sure you recycle your views (read the article!)

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

I'm near the beginning of Udacity's Android App Development course, and I figure this might be a better place for my stupid Java/Android-newbie questions than the Java thread. The course talks you through making a weather app. So, I've got the MainActivity and the fragment. At this point, I'm supposed to push the app to my phone and hit the refresh button. An expected crash happens, and I'm to look in the logcat and choose the right error from a list of four. The problem is that the error I get (NetworkOnMainThreadException) apparently isn't the right one. I'm guessing I did something unexpected, having come from C++ with not a whole lot of Java experience. What did I do wrong?

You did networking on the Ui thread, it sounds like. Strict Mode will crash you if you do that so as to make you aware that you did something really dumb. Use an async task and do something with the callback.

Welcome to event driven programming.

If you did not do that, a stack trace and relevant lines of code would help.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Uncomfortable Gaze posted:

There's a problem, calling doInBackground() will actually do the work in the UI thread. You need to call execute(), which will call the doInBackground method in a secondary thread.

This, you're directly calling that method. When you call execute, the task starts another thread which is then given that task and runs the doInBackground etc methods.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

Well it would've been nice if they'd loving mentioned that anywhere :psyduck:
Why would telling an async task to do in the background not ...do it in the background??

Because you're directly calling that method. It's meant as a callback. The documentation will both tell you this, and tell you exactly what to write to use this class.

Stop, think about what you're doing, and ask yourself why you believe that would, or could, work any differently. I understand that you're new to java AND android, but this would do the same thing in C++.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

I've realized that my starter app doesn't show the icon in the main view (or the brand-new other view either). I found this post on the Udacity forums suggesting that the fix is setting the targetSdkVersion to 20 rather than 21. This does indeed make the icon show up, but that doesn't seem like the right way to go about it. Any wisdom to impart?

Read the other answer in the link you posted.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

I'm having problems adding a new activity in AndroidManifest. Previously in this course, they've walked us through the steps of adding a new activity. I thought I'd done everything fine, and to the best of my ability have checked that the stuff I added for this new activity looks like the stuff for previous activities. However, in AndroidManifest.xml, Android Studio is complaining that the android:name".SettingsActivity" is not assignable to android.app.Activity. I've tried Googling for this error and reading the manifest documentation, but couldn't find anything that would explain why I might be getting this error.

Post the relevant snippet of manifest code, along with the package declaration line and class declaration line of your activity.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

Crap, I meant to include the manifest code.

AndroidManifest.xml
XML code:
<activity
    android:name=".SettingsActivity"
    android:label="@string/title_activity_settings"
    android:parentActivityName=".MainActivity" >
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="MainActivity" />
</activity>
Package declaration is package com.example.ben.sunshine;, class declaration is public class SettingsActivity extends PreferenceFragment implements Preference.OnPreferenceChangeListener.

PreferenceFragment is not a subclass of Activity.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

hooah posted:

Ok. I don't understand what that implies. They told us if we wanted to target Honeycomb+ to use PreferenceFragment rather than PreferenceActivity.

It means that you placed a not-activity peg into an activity hole. Create an activity to hold the fragment and point to that in your manifest.

Also, OO fundamentals :negative:

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
You're using the support library, which provides fragments to older devices which do not run Android 3.0 or above. Fragments were added in 3.0. You use the supportFragmentManager for classes that extend android.support.v4.app.Fragment, which SettingsFragment does not. There's no native support version, but others have made their own. Alternately, use SettingsActivity.

If you want to limit yourself to 3.0 and up (you probably do honestly) don't use support fragments, instead just use fragments and call getFragmentManager.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Splinter posted:

I'm just getting started with Android development, and also am in the market for a new phone. What should I be looking for in a phone from a developer's point of view? I unfortunately can't get a Nexus phone because I'm on Verizon and don't want something as big as the 6. Is OS update speed and long term support the primary thing I should be looking for, or are there other important aspects as well (e.g. runs stock Android w/ no third party launcher)? Do you guys typically use your actual phone for development, or have dedicated development devices?

Only nexus phones typically run stock Android. Anything else is going to have the manufacturer's special flavor with all of its awful quirks, coupled with the bloatware and restrictions that the carrier enforced (hope you didn't feel like tethering!). Of course, you can find a phone that can be rooted and flashed with another rom like Cyanogenmod, but that's another story and there's a subforum to discuss that.

People typically use their own phone for development, unless testing particular OS levels, screen sizes, etc from what I've seen. It's important to note if you're coming from iOS dev that Android uses full emulators, not simulators, when testing without a physical device. So, be sure your computer supports virtualization as required or you're in for a relatively painful experience.

As far as what to get, really just try and get a device with relatively recent hardware. You could just get a tablet if you're not doing anything telephony related to be totally honest.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
N4 might be pushing it for development. N5 is still reasonable.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Edit: wow did I ever misread that post. Yeah, working around device specific bugs is a big PITA that you don't really get with iOS.

Volmarias fucked around with this message at 17:43 on Dec 27, 2014

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

SimonChris posted:


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?

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?

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

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.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

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.
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.

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:
public void onClick(View v) {
  int choice = 0;
  if (v == paperButton) { 
    choice = 1;
  } else if (v == scissorsButton) {
    choice = 2;
  } else if (v == rockButton) {
    choice = 3;
  }
  mGameplay.setChoice(choice);
  ...
That said, to address your initial question, the best (and really only) way to start a loop without locking the UI thread is to start up a Thread. There are various helper classes you can use for this, such as AsyncTask (which may or may not be appropriate for your needs), but I'd argue that you really don't need a loop here; all you need is to update your countdown timer text, which you're doing, and to have an event occur when the countdown finishes (which you're doing).

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

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.

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.

Absolutely true, and probably a better solution on both counts.

Adbot
ADBOT LOVES YOU

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
If you haven't yet, read the Oracle java tutorials. The ones about multi threading will help answer a lot of your questions.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply