developing better debug_components
TRANSCRIPT
Developing Better Debug ComponentsMercari, Inc. Tomoaki Imai
07/30/2015 @shibuya.apk
Hi I’m TomoAndroid Developer
Joined Mercari, Inc. Mar,2014
Focusing on US app development
twitter: @tomoaki_imai
github: tomoima525
How debugging goes at Mercari
Debug View Configure settings that affect the whole app
• Api domain configuration
• Debug logout
• Open specific dialogs & screens directly
Debug MenuDebugging functions that you want to use at each screens
Things you don’t always need to see at Debug View
Debug Menu Functions• Auto Inputs
• Device Info
• Activity Info
• Heap size
• Screen dpi
• GCM ID
• Refresh master data etc.
2 tips for debug functions
• Get the debug-related source code out of the production
• Control a visibility of the debug menu
2 tips for debug functions
• Get the debug-related source code out of the production
• Control a visibility of the debug menu
Modularize debug functions
public class DebugView { public static void init(Context context, LinearLayout layout){ // Do nothing }}
Modularize debug functions
public class DebugView { public static void init(Context context, LinearLayout layout) { new DebugView(context, layout); } private DebugView(Context context, LinearLayout layout) { LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View debugView = layoutInflater.inflate(R.layout.layout_debug, null); // Set debug views ... layout.addView(debugView); }}
/src/release/…/DebugView.java
/src/debug/…/DebugView.java
// Any Activity or Fragment where you want to set DebugView.// ex) SettingFragment.java
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_setting,
container, false); // … LinearLayout layout = (LinearLayout)
view.findViewById(R.id.debug_view); DebugView.init(getBaseActivity(),layout); return view;}
Modularize debug functions
2 tips for debug functions
• Get the debug-related source code out of the production
• Control a visibility of the debug menu
Control visibility of debug menu
Control visibility of debug menu
public class MenuModule { private final static int GROUP_ID = Integer.MAX_VALUE;
public void onCreateOptionsMenu(Menu menu){ if(!LocalStorageUtil.getBoolean(S.is_debug_menu_visible)) return; // Set group id so that we can control visibility! menu.add(GROUP_ID, 100, 0, "Input"); //... Add menus } public void setVisibility(Menu menu, boolean isVisible){ for(int i = 0, length = menu.size(); i < length; i++ ){ MenuItem menuItem = menu.getItem(i); if(menuItem.getGroupId() == GROUP_ID){ menuItem.setVisible(isVisible); //Set visibility } } }}
public class BaseActivity { mMenuModule = new MenuModule(this);
// Called only once @Override public boolean onCreateOptionsMenu(Menu menu) { mMenuModule.onCreateOptionsMenu(menu); return super.onCreateOptionsMenu(menu); }
// Called every time menu is shown @Override public boolean onPrepareOptionsMenu(Menu menu) { mMenuModule.setVisibility(menu,
LocalStorageUtil.getBoolean(S.is_debug_menu_visible, false)); return super.onPrepareOptionsMenu(menu); }}
Control visibility of debug menu
public class DebugView {
private void changeDebugMenu(boolean isDebugMenuVisible){ // Save the state in Shared preference LocalStorageUtil.putBoolean(S.is_debug_menu_visible,
isDebugMenuVisible); debugMenuButton .setText(isDebugMenuVisible ? R.string.on : R.string.off); debugMenuButton .setBackgroundResource(isDebugMenuVisible ? R.drawable.indicator_on :R.drawable.indicator_off); // Update menu MyApplication .getContext().getCurrentActivity().invalidateOptionsMenu(); }}
Control visibility of debug menu
Wrap up
• Modularise debug components and get rid of them out from production
• Control the visibility of debug menu to avoid effects on usability