Redux was a cool idea. I was unsure at first questioning whether the performance hit and the architecture were worth it. I wasn't really given the choice as it was for my new job. So I agreed to go with it and hit the ground running. Only to discover it was like hitting my face on the ground, again, and again, and again.
TeenKoder
Tuesday, August 7, 2018
Redux or Ridiculous?
Redux was a cool idea. I was unsure at first questioning whether the performance hit and the architecture were worth it. I wasn't really given the choice as it was for my new job. So I agreed to go with it and hit the ground running. Only to discover it was like hitting my face on the ground, again, and again, and again.
Wednesday, August 9, 2017
Age Should Not Affect Salary
Recently I was having a conversation about my previous employer, not going to mention who they were here as I don't want to put a negative connotation on the company so for the rest of this article I will refer to them as Android World Co (AWC). I mentioned that I left because I was only making $12 an hour as a Junior Android Developer.
My co-worker who we'll call Henry for the purpose of this post shot back at me "Well you were just out of high school!!"
Really Henry? So my age of 18 years old says that I can't make a fair salary for my knowledge and skills? Arguably after not long of working at AWC, my supervisor told me he was impressed and was going to give me a $1 raise. At the time, I thought that was tremendous, someone recognized that I knew my stuff.
However, I didn't want a $1 raise. I wanted to be paid my fair market value, I knew I was worth more than that.
To put this in perspective lets say we have 2 candidates (C1 and C2) who are both applying to be and Android Developer at Android National Co (ANC).
C1 has a bachelor's degree from the University of Utah, he barely scratched through college, doesn't know how to use git except with using a GUI, doesn't really want to learn how to use git. C1 doesn't really want to learn new technologies, but will if he must. Kotlin, Java 8, yeah in your dreams, C1 thinks that these are just a waste of time because he doesn't want to put in the effort to learn these.
C2 has a high school diploma, and every night after school would spend 4-8 hours learning and programming because he loved it and really wanted to become a great developer. C2 has a passion for learning and wants to absorb everything he can about Android. C2 goes to local meetups to learn from his peers and asks questions from other developers to make himself better. C2 wants to learn Kotlin, Java 8, all the latest and greatest and stay at the top of his game.
Who should get the job? If you ask me, C2 should. I don't want an employee who doesn't care. I don't want an employee who isn't willing to learn unless forced.
I want C1. C1 may not have the same training from a University. C1 survived 4 years of grueling late nights. No sleep. He stayed up every night til 4 AM learning about programming, woke up at 7 AM to go to school and graduate high school. He learned what it was like to work for what you want.
I am definitely C1. Sure I may be biased on this, but don't; I repeat DON'T think that someone should be paid less just because they just graduated. Pay someone based on their skills and knowledge.
Monday, November 14, 2016
Activity's and Fragments
When is it better to use a Fragment over an Activity?
When is this useful?
On a mobile phone you can easily use an animation to slide, expand, fade or whatever animation works best for you. On a tablet however this makes your app more user friendly across a wider range of devices.
How do I pass information to the Activity?
Passing data from the Fragment to the parent Activity is fairly simple. Within the fragment make a call to getActivity() and you can use all of the accessor methods available in the parent Activity.
Thursday, November 10, 2016
Android - Handlers and Data Leaks
I am writing this because I recently I was being tested on my Android knowledge, and although I knew about data leaks and how to solve the data leaks, courtesy of Android Studio, I didn't know what was actually causing the data leaks.
If not properly used a Handler will hold a reference to the context of the activity from which it was created which therefore prevents the garbage collector from performing garbage collection on the Activity from which you instantiated the handler. Here's a good example of what NOT to do.
class FooActivity extends Activity { private Handler mHandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_foo); mHandler = createMyHandler(); createBackgroundThreadWithHandler(mHandler); } private Handler createMyHandler() { return new Handler() { @Override handleMessage(Message msg) { super.handleMessage(msg); Toast.makeText(FooActivity.this, "Hi", Toast.LENGTH_SHORT).show(); } }; } }
The above code is not good because we have no idea how long the BackgroundThreadWithHandler will be alive, however as long as it is, it will have a reference to the handler which will have a reference to the context of FooActivity.
So now lets look at the proper way to handle dealing with Handlers. We need to be able to create the handler, however we can't let the handler hold a strong reference to the Context/Activity.
class FooActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_foo); createBackgroundThreadWithHandler(new MyHandler(FooActivity.this)); } void sayHi() { Toast.makeText(FooActivity.this, "Hi", Toast.LENGTH_SHORT).show(); } static class MyHandler extends Handler { MyHandler(FooActivity fooActivity) { weakFooActivity = new WeakReference(fooActivity); } @Override handleMessage(Message msg) { super.handleMessage(msg); FooActivity fooActivity = weakFooActivity.get(); if (fooActivity != null) { fooActivity.sayHi(); } } } }
This example keeps a weak reference to FooActivity which allows the garbage collector to still perform garbage collection on FooActivity.
Wednesday, December 16, 2015
libGDX Android Text Input
However the problem I was facing today was dealing with Android text input. I am amid creating my own library add-on for libGDX that provides a lot of the same GUI menu like items provided with Android, however they are directly for libGDX and use within games and game menus. I have been working on Buttons, Layouts, Text Inputs, Labels, Custom Widgets, Loading Bars, you name it. However when it came to text input from the soft-keyboard provided in Android, there were bugs that were all dependent on device, or if they weren't using Google keyboard. For a game that is supposed to run flawlessly on any device on which it can be installed, this wouldn't cut it. So I did a bit of popping around on the internet and came up with this way of creating a popup for Android that would take input.
@Override
public void input(String input) {
text = input;
}
@Override
public void canceled() {
}
};
Gdx.input.getTextInput(inputListener, hint, text, "");
This worked excellently. It gave me a little popup that allowed for me to input text, then it would make the text in the widget, which I call EditText after Android EditText widget, change to be whatever I put in the popup. Everything was great. Just one problem. The popup looked almost 'prehistoric' or at least it was Android Froyo styling. Not exactly my taste. I like Lollipop much better, but I also supported back to Android Jelly Bean. So I did the next best thing.
In my Android part of the project I went into styles.xml and changed one part so that the android Dialog would look how I wanted it to.
Before:
<resources> <style name="GdxTheme" parent="android:Theme"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowAnimationStyle">@android:style/Animation</item> <item name="android:windowNoTitle">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowFullscreen">true</item> </style> </resources>
After:
<resources>
<style name="GdxTheme" parent="android:Theme.DeviceDefault">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowFullscreen">true</item>
</style>
</resources>
Changing the parent of GdxTheme from android:Theme to android:Theme.DeviceDefault will make it so that the popup matches whatever OS you're running, be it KitKat, JellyBean, or Marshmallow.
That's all for today. Hope this helps anyone else struggling with this problem.
Wednesday, July 29, 2015
First Internship
Friday, October 24, 2014
Android Grow View Dynamically
private int startHeight;
private int deltaHeight; // distance between start and end height
/**
* constructor, do not forget to use the setParams(int, int) method before
* starting the animation
* @param v
*/
public ResizeAnimation (View v) {
this.view = v;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height = (int) (startHeight + deltaHeight * interpolatedTime);
view.requestLayout();
}
/**
* set the starting and ending height for the resize animation
* starting height is usually the views current height, the end height is the height
* we want to reach after the animation is completed
* @param start height in pixels
* @param end height in pixels
*/
public void setHeightDifference(int start, int end) {
this.startHeight = start;
deltaHeight = end - startHeight;
}
/**
* set the starting and ending width for the resize animation
* starting width is usually the views current width, the end width is the width
* we want to reach after the animation is completed
* @param start height in pixels
* @param end height in pixels
*/
public void setHeightDifference(int start, int end) {
this.startWidth = start;
deltaWidth = end - startWidth;
}
/**
* set the duration for the hideshowanimation
*/
@Override
public void setDuration(long durationMillis) {
super.setDuration(durationMillis);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
clickableLayout.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View V){
RelativeLayout v = (RelativeLayout) V;
// getting the layoutparams might differ in your application, it depends on the parent layout
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
a.setDuration(500);
a.setParams(lp.height, newHeight); relativeLayout.startAnimation(a);
v.startAnimation(a)
}
}
Friday, July 18, 2014
Passing Data Between Threads (Java)
Currently I'm working on a new desktop app for a family reunion. I started out hoping this would be a two day and done, but when I actually started coding I realized I was in a bit deeper than I had previously thought. So here's to explaining my app.
This app requires 2 windows to be constantly open and running, however both of these windows need constant communication.
The audience cannot see the control window, but rather only the pretty display, this allows for the audience to never see an annoying mouse moving around. I couldn't figure out any other way to do this the way I want with libgdx without multi threading.
I started this project by trying to create two windows using libgdx (however I didn't actually want libgdx for control) but I wanted to see if it was possible. I quickly learned that openAL does not allow libgdx to do that, so I quickly switched over to Swing to make sure that I could in fact actually still accomplish 2 windows (and not "pop ups").
So I started working at this app got a bit of the GUI out of the way then went on to the next challenge of communicating between these threads. Now the way that libgdx works you can't manage the threads a whole lot from the original class to start the threads, or at least in terms of passing around data.
The solution? A class I call DataPassage, with all variables being static. The static variables allow me to access the data from anywhere without having to directly pass it to each class. DataPassage nicely handles all variables inside. This helps in two ways.
#1) Cuts down in data on the heap.
#2) Organizes all variables and keeps it all in sync.
Now would I recommend this for all variables in every situation? No, but definitely useful in a lot of situations. Would I recommend this if you are struggling in a situation like mine? Yes. Just be sure to not be storing the variables in all 3 classes, and rather only in the DataPassage class.
Monday, July 14, 2014
MinerMan
https://play.google.com/store/apps/details?id=com.coppercow.minerman
Here's the link to my latest game I've released called MinerMan!
If you enjoy it please tell you're friends and family!
Thursday, February 27, 2014
OK Google!
Yesterday Android developers announced a very long awaited launcher called the Google Now Launcher available at no cost on Google Play. This launcher gives a more current look and feel to a stock Google phone. This launcher also gives accessibility to "OK Google" from the home screen. This means that from the home screen if you say "OK Google" aloud Google will pop up so you can tell it what to do. Google Now launcher made its first appearance on the Nexus 5 device from Google, but did not come stock with Android 4.4 so this is rather a big deal for any Android users who do not want to pay for a Nexus 5, but still want the look, feel, and capabilities(within reason) of the Nexus 5. The new Google Now launcher is available for download here: https://play.google.com/store/apps/details?id=com.google.android.launcher