From 61cf133106847d013644a73f687857729cd1d8f3 Mon Sep 17 00:00:00 2001 From: "Michael A. Walker" Date: Wed, 11 Jun 2014 12:18:38 -0500 Subject: [PATCH 1/2] Improved AndroidPlatformStrategy & Factory, to avoid memory leak of Context... by storying reference to TextView (which is a subclass of View, which contains a reference to the Context) Now, Factory only takes in one Object, and AndroidPlatformStrategy uses method to 'reach' the TextView. --- .../vuum/mocca/AndroidPlatformStrategy.java | 26 +--- .../src/edu/vuum/mocca/Main.java | 3 +- .../vuum/mocca/OutputTextViewActivity.java | 12 ++ .../src/edu/vuum/mocca/PingPongActivity.java | 31 +++-- .../vuum/mocca/PlatformStrategyFactory.java | 120 ++++++++---------- 5 files changed, 93 insertions(+), 99 deletions(-) create mode 100644 assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/OutputTextViewActivity.java diff --git a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/AndroidPlatformStrategy.java b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/AndroidPlatformStrategy.java index bc684b5ce..74d2e2402 100644 --- a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/AndroidPlatformStrategy.java +++ b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/AndroidPlatformStrategy.java @@ -3,8 +3,6 @@ import java.lang.ref.WeakReference; import java.util.concurrent.CountDownLatch; -import android.app.Activity; -import android.widget.TextView; import android.util.Log; /** @@ -16,24 +14,14 @@ * "Concrete Strategy" in the Strategy pattern. */ public class AndroidPlatformStrategy extends PlatformStrategy -{ - /** TextViewVariable. */ - private TextView mTextViewOutput; - +{ /** Activity variable finds gui widgets by view. */ - private WeakReference mActivity; + private WeakReference mActivity; - public AndroidPlatformStrategy(Object output, - final Object activityParam) + public AndroidPlatformStrategy(final OutputTextViewActivity activityParam) { - /** - * A textview output which displays calculations and - * expression trees. - */ - mTextViewOutput = (TextView) output; - - /** The current activity window (succinct or verbose). */ - mActivity = new WeakReference((Activity) activityParam); + /** The current activity window (succinct or verbose). */ + mActivity = new WeakReference(activityParam); } /** @@ -61,7 +49,7 @@ public void print(final String outputString) /** Indicate that a game thread has finished running. */ public void done() - { + { // TODO - You fill in here. } @@ -79,4 +67,4 @@ public void errorLog(String javaFile, String errorMessage) { Log.e(javaFile, errorMessage); } -} +} \ No newline at end of file diff --git a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/Main.java b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/Main.java index 9026c80e6..7d6e982ab 100644 --- a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/Main.java +++ b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/Main.java @@ -20,8 +20,7 @@ public static void main(String[] args) * ConsolePlatform. */ PlatformStrategy.instance - (new PlatformStrategyFactory(System.out, - null).makePlatformStrategy()); + (new PlatformStrategyFactory(System.out).makePlatformStrategy()); /** Initializes the Options singleton. */ Options.instance().parseArgs(args); diff --git a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/OutputTextViewActivity.java b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/OutputTextViewActivity.java new file mode 100644 index 000000000..d535d3ce5 --- /dev/null +++ b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/OutputTextViewActivity.java @@ -0,0 +1,12 @@ +package edu.vuum.mocca; + +import android.app.Activity; +import android.widget.TextView; + +/** + * Abstract class, that defines the the getOutputTextView() method. + */ +public abstract class OutputTextViewActivity extends Activity { + + abstract TextView getOutputTextView(); +} diff --git a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PingPongActivity.java b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PingPongActivity.java index 3d283d399..4cffa92de 100644 --- a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PingPongActivity.java +++ b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PingPongActivity.java @@ -1,6 +1,5 @@ package edu.vuum.mocca; -import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; @@ -11,7 +10,7 @@ * * @brief Initial start up screen for the android GUI. */ -public class PingPongActivity extends Activity { +public class PingPongActivity extends OutputTextViewActivity { /** TextView that PingPong will be "played" upon */ private TextView mAndroidPingPongOutput; @@ -28,19 +27,16 @@ protected void onCreate(Bundle savedInstanceState) { // Sets the content view to the xml file, activity_ping_pong. setContentView(R.layout.activity_ping_pong); - mAndroidPingPongOutput = - (TextView) findViewById(R.id.pingpong_output); + mAndroidPingPongOutput = (TextView) findViewById(R.id.pingpong_output); mPlayButton = (Button) findViewById(R.id.play_button); // Initializes the Platform singleton with the appropriate // Platform strategy, which in this case will be the // AndroidPlatform. - PlatformStrategy.instance - (new PlatformStrategyFactory - (mAndroidPingPongOutput, - this).makePlatformStrategy()); + PlatformStrategy.instance(new PlatformStrategyFactory(this) + .makePlatformStrategy()); - // Initializes the Options singleton. + // Initializes the Options singleton. Options.instance().parseArgs(null); } @@ -49,11 +45,10 @@ public void playButtonClicked(View view) { if (mGameState == PLAY) { // Use a factory method to create the appropriate type of // OutputStrategy. - PlayPingPong pingPong = - new PlayPingPong(PlatformStrategy.instance(), - Options.instance().maxIterations(), - Options.instance().maxTurns(), - Options.instance().syncMechanism()); + PlayPingPong pingPong = new PlayPingPong( + PlatformStrategy.instance(), Options.instance() + .maxIterations(), Options.instance().maxTurns(), + Options.instance().syncMechanism()); // Play ping-pong with the designated number of // iterations. @@ -73,4 +68,12 @@ public void playButtonClicked(View view) { mGameState = RESET; } } + + /** + * grant access of the Output TextView to the AndroidPlatformStrategy + */ + @Override + TextView getOutputTextView() { + return mAndroidPingPongOutput; + } } diff --git a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PlatformStrategyFactory.java b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PlatformStrategyFactory.java index 95d6bb962..2ace44592 100644 --- a/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PlatformStrategyFactory.java +++ b/assignments/week-5-assignment-4/W5-A4-Android/src/edu/vuum/mocca/PlatformStrategyFactory.java @@ -2,106 +2,98 @@ import java.util.HashMap; +import android.app.Activity; + /** * @class PlatformStrategyFactory * * @brief This class is a factory that is responsible for building the * designated @a PlatformStrategy implementation at runtime. */ -public class PlatformStrategyFactory -{ - /** - * This interface uses the Strategy pattern to create @a - * PlatformStrategy implementations at runtime. +public class PlatformStrategyFactory { + /** + * This interface uses the Strategy pattern to create @a PlatformStrategy + * implementations at runtime. */ - private static interface IPlatformStrategyFactoryStrategy - { + private static interface IPlatformStrategyFactoryStrategy { public PlatformStrategy execute(); } - + /** * Enumeration distinguishing platforms Android from plain ol' Java. */ public enum PlatformType { - ANDROID, - PLAIN_JAVA + ANDROID, PLAIN_JAVA } - + /** - * HashMap used to map strings containing the Java platform names - * and dispatch the execute() method of the associated @a PlatformStrategy + * HashMap used to map strings containing the Java platform names and + * dispatch the execute() method of the associated @a PlatformStrategy * implementation. */ - private HashMap mPlatformStrategyMap = - new HashMap(); - - /** - * Ctor that stores the objects that perform output for a - * particular platform, such as ConsolePlatformStrategy or the - * AndroidPlatformStrategy. + private HashMap mPlatformStrategyMap = new HashMap(); + + /** + * Ctor that stores the objects that perform output for a particular + * platform, such as ConsolePlatformStrategy or the AndroidPlatformStrategy. */ - public PlatformStrategyFactory(final Object output, - final Object activity) - { - /** - * The "The Android Project" string maps to a command object - * that creates an @a AndroidPlatformStrategy implementation. + public PlatformStrategyFactory(final Object output) { + /** + * The "The Android Project" string maps to a command object that + * creates an @a AndroidPlatformStrategy implementation. */ mPlatformStrategyMap.put(PlatformType.ANDROID, - new IPlatformStrategyFactoryStrategy() - { - /** - * Receives the three parameters, input - * (EditText), output (TextView), activity - * (activity). - */ - public PlatformStrategy execute() - { - return new AndroidPlatformStrategy(output, - activity); - } - }); - - /** - * The "Sun Microsystems Inc." string maps to a command object - * that creates an @a ConsolePlatformStrategy implementation. + new IPlatformStrategyFactoryStrategy() { + /** + * Receives the three parameters, input (EditText), output + * (TextView), activity (activity). + * + * @throws Exception + */ + public PlatformStrategy execute() { + if (output instanceof OutputTextViewActivity) { + return new AndroidPlatformStrategy( + (OutputTextViewActivity) output); + } else { + return new AndroidPlatformStrategy(null); + } + } + }); + + /** + * The "Sun Microsystems Inc." string maps to a command object that + * creates an @a ConsolePlatformStrategy implementation. */ mPlatformStrategyMap.put(PlatformType.PLAIN_JAVA, - new IPlatformStrategyFactoryStrategy() - { - public PlatformStrategy execute() - { - return new ConsolePlatformStrategy(output); - } - }); + new IPlatformStrategyFactoryStrategy() { + public PlatformStrategy execute() { + return new ConsolePlatformStrategy(output); + } + }); } - /** - * Returns the name of the platform in a string. e.g., Android or - * a JVM. + /** + * Returns the name of the platform in a string. e.g., Android or a JVM. */ - public static String platformName() - { + public static String platformName() { return System.getProperty("java.specification.vendor"); } - - /** - * Returns the type of the platformm e.g. Android or - * a JVM. + + /** + * Returns the type of the platformm e.g. Android or a JVM. */ public static PlatformType platformType() { - if(platformName().indexOf("Android") >= 0) + if (platformName().indexOf("Android") >= 0) return PlatformType.ANDROID; - else + else return PlatformType.PLAIN_JAVA; } - /** + /** * Create a new @a PlatformStrategy object based on underlying Java * platform. */ - public PlatformStrategy makePlatformStrategy() - { + public PlatformStrategy makePlatformStrategy() { PlatformType type = platformType(); return mPlatformStrategyMap.get(type).execute(); From 4621a58aae9422fb08beaa026bf24df00bcdf5dd Mon Sep 17 00:00:00 2001 From: "Michael A. Walker" Date: Tue, 1 Jul 2014 13:21:32 -0500 Subject: [PATCH 2/2] A possible update teo the AcronymApplication, fixes listview layout, and moved ServiceConnection creation to a Factory class. --- .../res/layout/acronym_data_row.xml | 15 +- ex/AcronymApplication/res/values/strings.xml | 2 +- .../src/edu/vuum/mocca/AcronymActivity.java | 435 +++++++++--------- .../AcronymServiceConnectionFactory.java | 37 ++ 4 files changed, 254 insertions(+), 235 deletions(-) create mode 100644 ex/AcronymApplication/src/edu/vuum/mocca/AcronymServiceConnectionFactory.java diff --git a/ex/AcronymApplication/res/layout/acronym_data_row.xml b/ex/AcronymApplication/res/layout/acronym_data_row.xml index 6dc1362ed..da054b381 100644 --- a/ex/AcronymApplication/res/layout/acronym_data_row.xml +++ b/ex/AcronymApplication/res/layout/acronym_data_row.xml @@ -9,28 +9,29 @@ tools:context="edu.vu.isis.serviceparcelableexasync2.MainActivity$PlaceholderFragment" > + android:text="@string/year_string" /> + android:paddingLeft="5dp" + android:layout_toRightOf="@+id/db_refs" + android:text="@string/result_string" /> \ No newline at end of file diff --git a/ex/AcronymApplication/res/values/strings.xml b/ex/AcronymApplication/res/values/strings.xml index 79b8d5f84..5361188aa 100644 --- a/ex/AcronymApplication/res/values/strings.xml +++ b/ex/AcronymApplication/res/values/strings.xml @@ -4,7 +4,7 @@ Settings Result Result - References + Refs Year diff --git a/ex/AcronymApplication/src/edu/vuum/mocca/AcronymActivity.java b/ex/AcronymApplication/src/edu/vuum/mocca/AcronymActivity.java index d7d2fc6ca..9b8089c19 100644 --- a/ex/AcronymApplication/src/edu/vuum/mocca/AcronymActivity.java +++ b/ex/AcronymApplication/src/edu/vuum/mocca/AcronymActivity.java @@ -19,234 +19,215 @@ * The main Activity that launches the screen users will see. */ public class AcronymActivity extends Activity { - /** - * Used for logging purposes. - */ - static private String TAG = AcronymActivity.class.getCanonicalName(); - - /** - * The ListView that will display the results to the user. - */ - private ListView mListView; - - /** - * A custom ArrayAdapter used to display the list of AcronymData objects. - */ - private AcronymDataArrayAdapter adapter; - - /** - * Acronym entered by the usre. - */ - private EditText mEditText; - - /** - * The implementation of the AcronymResults AIDL Interface. - * Should be passed to the WebService using the - * AcronymRequest.expandAcronym() method. - * - * This implementation of AcronymResults.Stub plays the role of - * Invoker in the Broker Pattern. - */ - private AcronymResults.Stub mAcronymResults = new AcronymResults.Stub() { - /** - * This method is called back by the Service to return the - * results. - */ - @Override + /** + * Used for logging purposes. + */ + static private String TAG = AcronymActivity.class.getCanonicalName(); + + /** + * The ListView that will display the results to the user. + */ + private ListView mListView; + + /** + * A custom ArrayAdapter used to display the list of AcronymData objects. + */ + private AcronymDataArrayAdapter adapter; + + /** + * Acronym entered by the usre. + */ + private EditText mEditText; + + /** + * The implementation of the AcronymResults AIDL Interface. Should be passed + * to the WebService using the AcronymRequest.expandAcronym() method. + * + * This implementation of AcronymResults.Stub plays the role of Invoker in + * the Broker Pattern. + */ + private AcronymResults.Stub mAcronymResults = new AcronymResults.Stub() { + /** + * This method is called back by the Service to return the results. + */ + @Override public void sendResults(final List acronymDataList) - throws RemoteException { - // This method runs in a separate Thread as per the - // behavior of the Android Binder framework, so we - // need to explicitly post a runnable containing the - // results back to the UI Thread. - runOnUiThread(new Runnable() { - public void run() { - displayResults(acronymDataList); - } - }); - } + throws RemoteException { + // This method runs in a separate Thread as per the + // behavior of the Android Binder framework, so we + // need to explicitly post a runnable containing the + // results back to the UI Thread. + runOnUiThread(new Runnable() { + public void run() { + displayResults(acronymDataList); + } + }); + } }; - /** - * This GenericServiceConnection is used to receive results after - * binding to the AcronymServiceAsync Service using bindService(). - */ - private GenericServiceConnection mServiceConnectionAsync = - new GenericServiceConnection - (new GenericServiceConnection.InterfaceFactory() { - public AcronymRequest asInterface(IBinder service) { - return AcronymRequest.Stub.asInterface(service); - }}); - - /** - * This GenericServiceConnection is used to receive results after - * binding to the AcronymServiceSync Service using bindService(). - */ - private GenericServiceConnection mServiceConnectionSync = - new GenericServiceConnection - (new GenericServiceConnection.InterfaceFactory() { - public AcronymCall asInterface(IBinder service) { - return AcronymCall.Stub.asInterface(service); - }}); - - /** - * Called when the activity is starting - this is where most - * initialization should go. - */ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Get references to the UI components. - setContentView(R.layout.activity_main); - - mEditText = (EditText) findViewById(R.id.editText1); - mListView = (ListView) findViewById(R.id.listView1); - } - - /* - * Initiate the asynchronous acronym lookup. - */ - public void expandAcronymAsync(View v) { - AcronymRequest acronymRequest = - mServiceConnectionAsync.getInterface(); - - if (acronymRequest != null) { - // Get the acronym entered by the user. - final String acronym = mEditText.getText().toString(); - - hideKeyboard(); - - try { - // Invoke a one-way AIDL call, which does not block - // the client. The results are returned via the - // sendResults() method of the mAcronymResults - // callback object, which runs in a Thread from the - // Thread pool managed by the Binder framework. - acronymRequest.expandAcronym(mAcronymResults, - acronym); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException:" + e.getMessage()); - } - } else { - Log.d(TAG, "acronymRequest was null."); - } - } - - /* - * Initiate the synchronous acronym lookup. - */ - public void expandAcronymSync(View v) { - final AcronymCall acronymCall = - mServiceConnectionSync.getInterface(); - - if (acronymCall != null) { - // Get the acronym entered by the user. - final String acronym = mEditText.getText().toString(); - - hideKeyboard(); - - // Use mAcronymCall to download the Acronym data in a - // separate Thread and then display it in the UI Thread. - // We use a separate Thread to avoid blocking the UI - // Thread. - new Thread(new Runnable() { - public void run () { - try { - Log.d(TAG, - "Calling twoway AcronymServiceSync.expandAcronym()"); - - // Download the expanded acronym via a - // synchronous two-way method call. - final List acronymDataList = - acronymCall.expandAcronym(acronym); - - // Display the results in the UI Thread. - runOnUiThread(new Runnable() { - public void run() { - displayResults(acronymDataList); - } - }); - } catch (RemoteException e1) { - e1.printStackTrace(); - } - } - }).start(); - } else { - Log.d(TAG, "mAcronymCall was null."); - } - } - - /** - * Display the results to the screen. - * - * @param results - * List of Resultes to be displayed. - */ - protected void displayResults(List results) { - // Create custom ListView Adapter and fill it with our data. - if (adapter == null) { - // Create a local instance of our custom Adapter for our - // ListView. - adapter = new AcronymDataArrayAdapter(this, results); - } else { - // If adapter already existed, then change data set. - adapter.clear(); - adapter.addAll(results); - adapter.notifyDataSetChanged(); - } - - // Set the adapter to the ListView. - mListView.setAdapter(adapter); - } - - /** - * Hook method called when the MainActivity becomes visible to - * bind the Activity to the Services. - */ - @Override - public void onStart() { - super.onStart(); - - // Launch the Bound Services if they aren't already running - // via a call to bindService(), which binds this activity to - // the Acronym* Services if they aren't already bound. - if (mServiceConnectionAsync.getInterface() == null) - bindService(AcronymServiceAsync.makeIntent(this), - mServiceConnectionAsync, - BIND_AUTO_CREATE); - - if (mServiceConnectionSync.getInterface() == null) - bindService(AcronymServiceSync.makeIntent(this), - mServiceConnectionSync, - BIND_AUTO_CREATE); - } - - /** - * Hook method called when the MainActivity becomes completely hidden to - * unbind the Activity from the Services. - */ - @Override - public void onStop() { - super.onStop(); - - // Unbind the Async Service if it is connected. - if (mServiceConnectionAsync.getInterface() != null) - unbindService(mServiceConnectionAsync); - - // Unbind the Sync Service if it is connected. - if (mServiceConnectionSync.getInterface() != null) - unbindService(mServiceConnectionSync); - } - - /** - * Hide the keyboard after a user has finished typing the url. - */ - private void hideKeyboard() { - InputMethodManager mgr = - (InputMethodManager) getSystemService - (Context.INPUT_METHOD_SERVICE); - mgr.hideSoftInputFromWindow(mEditText.getWindowToken(), - 0); - } + /** + * This GenericServiceConnection is used to receive results after binding to + * the AcronymServiceAsync Service using bindService(). + */ + private GenericServiceConnection mServiceConnectionAsync = AcronymServiceConnectionFactory + .newAcronumRequestConnection(); + /** + * This GenericServiceConnection is used to receive results after binding to + * the AcronymServiceSync Service using bindService(). + */ + private GenericServiceConnection mServiceConnectionSync = AcronymServiceConnectionFactory + .newAcronumCallConnection(); + + /** + * Called when the activity is starting - this is where most initialization + * should go. + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Get references to the UI components. + setContentView(R.layout.activity_main); + + mEditText = (EditText) findViewById(R.id.editText1); + mListView = (ListView) findViewById(R.id.listView1); + } + + /* + * Initiate the asynchronous acronym lookup. + */ + public void expandAcronymAsync(View v) { + AcronymRequest acronymRequest = mServiceConnectionAsync.getInterface(); + + if (acronymRequest != null) { + // Get the acronym entered by the user. + final String acronym = mEditText.getText().toString(); + + hideKeyboard(); + + try { + // Invoke a one-way AIDL call, which does not block + // the client. The results are returned via the + // sendResults() method of the mAcronymResults + // callback object, which runs in a Thread from the + // Thread pool managed by the Binder framework. + acronymRequest.expandAcronym(mAcronymResults, acronym); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException:" + e.getMessage()); + } + } else { + Log.d(TAG, "acronymRequest was null."); + } + } + + /* + * Initiate the synchronous acronym lookup. + */ + public void expandAcronymSync(View v) { + final AcronymCall acronymCall = mServiceConnectionSync.getInterface(); + + if (acronymCall != null) { + // Get the acronym entered by the user. + final String acronym = mEditText.getText().toString(); + + hideKeyboard(); + + // Use mAcronymCall to download the Acronym data in a + // separate Thread and then display it in the UI Thread. + // We use a separate Thread to avoid blocking the UI + // Thread. + new Thread(new Runnable() { + public void run() { + try { + Log.d(TAG, + "Calling twoway AcronymServiceSync.expandAcronym()"); + + // Download the expanded acronym via a + // synchronous two-way method call. + final List acronymDataList = acronymCall + .expandAcronym(acronym); + + // Display the results in the UI Thread. + runOnUiThread(new Runnable() { + public void run() { + displayResults(acronymDataList); + } + }); + } catch (RemoteException e1) { + e1.printStackTrace(); + } + } + }).start(); + } else { + Log.d(TAG, "mAcronymCall was null."); + } + } + + /** + * Display the results to the screen. + * + * @param results + * List of Resultes to be displayed. + */ + protected void displayResults(List results) { + // Create custom ListView Adapter and fill it with our data. + if (adapter == null) { + // Create a local instance of our custom Adapter for our + // ListView. + adapter = new AcronymDataArrayAdapter(this, results); + } else { + // If adapter already existed, then change data set. + adapter.clear(); + adapter.addAll(results); + adapter.notifyDataSetChanged(); + } + + // Set the adapter to the ListView. + mListView.setAdapter(adapter); + } + + /** + * Hook method called when the MainActivity becomes visible to bind the + * Activity to the Services. + */ + @Override + public void onStart() { + super.onStart(); + + // Launch the Bound Services if they aren't already running + // via a call to bindService(), which binds this activity to + // the Acronym* Services if they aren't already bound. + if (mServiceConnectionAsync.getInterface() == null) + bindService(AcronymServiceAsync.makeIntent(this), + mServiceConnectionAsync, BIND_AUTO_CREATE); + + if (mServiceConnectionSync.getInterface() == null) + bindService(AcronymServiceSync.makeIntent(this), + mServiceConnectionSync, BIND_AUTO_CREATE); + } + + /** + * Hook method called when the MainActivity becomes completely hidden to + * unbind the Activity from the Services. + */ + @Override + public void onStop() { + super.onStop(); + + // Unbind the Async Service if it is connected. + if (mServiceConnectionAsync.getInterface() != null) + unbindService(mServiceConnectionAsync); + + // Unbind the Sync Service if it is connected. + if (mServiceConnectionSync.getInterface() != null) + unbindService(mServiceConnectionSync); + } + + /** + * Hide the keyboard after a user has finished typing the url. + */ + private void hideKeyboard() { + InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + mgr.hideSoftInputFromWindow(mEditText.getWindowToken(), 0); + } } diff --git a/ex/AcronymApplication/src/edu/vuum/mocca/AcronymServiceConnectionFactory.java b/ex/AcronymApplication/src/edu/vuum/mocca/AcronymServiceConnectionFactory.java new file mode 100644 index 000000000..bbab18f3c --- /dev/null +++ b/ex/AcronymApplication/src/edu/vuum/mocca/AcronymServiceConnectionFactory.java @@ -0,0 +1,37 @@ +package edu.vuum.mocca; + +import android.os.IBinder; + +/** + * Factory Class to build the GenergicServiceConnection(s) desired, moving the + * code to this file does nothing but add to overall readability of + * AcronymActivity. + */ +public class AcronymServiceConnectionFactory { + + /** + * Create the AcronymRequest GenericServiceConnection. + * @return the ServiceConnection to use + */ + static public GenericServiceConnection newAcronumRequestConnection() { + return new GenericServiceConnection( + new GenericServiceConnection.InterfaceFactory() { + public AcronymRequest asInterface(IBinder service) { + return AcronymRequest.Stub.asInterface(service); + } + }); + } + + /** + * Create the AcronymCall GenericServiceConnection. + * @return the ServiceConnection to use + */ + static public GenericServiceConnection newAcronumCallConnection() { + return new GenericServiceConnection( + new GenericServiceConnection.InterfaceFactory() { + public AcronymCall asInterface(IBinder service) { + return AcronymCall.Stub.asInterface(service); + } + }); + } +}