Showing posts with label koding. Show all posts
Showing posts with label koding. Show all posts

Monday, November 14, 2016

Activity's and Fragments

Last summer during my internship I used Fragments quite often and as such for a while I understood at least the basics about Fragments, their use cases, and what strengths and weaknesses come with Fragments. Unfortunately, quite recently I had my knowledge tested on this and I learned quite quickly that I don't understand Fragments as good as I once did. So after going back and using Fragments over the weekend and reading the docs and as many tutorials as possible, I finally at least got a slight refresher on Fragments.


When is it better to use a Fragment over an Activity?


Well, actually they really just work hand in hand. An Activity will hold the context and everything you need for the Fragment, the Fragment however will store information and thus you can pass information easily through from Fragment to Fragment.

When is this useful?


Let's say for a minute that you are a general contractor and have 7 houses you're currently building. For each house you have information you need to know, but shouldn't be included in the list.

Now you could do a list like below where each item in the list is associated with an ID which you send through an intent to another activity. This might look great on phone with a relatively small screen, but on a larger device like a tablet, as you can see below, it could definitely look better.



This is where fragments come to the rescue. Let's go back to that list. Now lets say that each item in that list actually has a reference to a JobSite object that has all of the information about the job site. The fragment can pass objects through the activity to another fragment within the same Activity. Doing that you can fairly easily do something like this.


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

This post is mostly for my reference as I use Handlers a lot, but I'm still trying to get use to the idea of a WeakReference. Obviously this isn't rocket science, but up until about 9 months ago I used Handlers in a very improper way (my first example) and undoubtedly ended up with a lot of data leaks in any multi-threaded application I developed.

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

libGDX has its ups and its downs. It isn't perfect by any means, but I still believe it has a ton of potential especially with RoboVM at its side which makes it work wonderfully with iOS and still keeps it working great for Android and Desktop. I love the make it once, run it everywhere aspect that it provides. Also the same reason I love Java.

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.


Input.TextInputListener inputListener = new Input.TextInputListener() {
    @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.

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, February 3, 2014

Python IDE

Kind of a cool Python IDE(Integrated Development Environment) if you have internet. Most especially useful for Python development with the new Google Chromebook.  http://pythonfiddle.com/