Presentation is loading. Please wait.

Presentation is loading. Please wait.

Android 7: One Button Recursion and Debugging

Similar presentations


Presentation on theme: "Android 7: One Button Recursion and Debugging"— Presentation transcript:

1 Android 7: One Button Recursion and Debugging

2

3 Introduction This set of overheads begins with a simple app where the sendMessage() method is small, but contains some significant code It is a lead-in to debugging As soon as code gets more complicated you have to be able to debug Android Studio has built-in debugging features, but sometimes the simple ways are the best…

4 7.1 The OneButtonRecursion app
7.2 Unhelpful Error Messages 7.3 Logging Output

5 7.1 The OneButtonRecursion app

6 Screen shots for the one button recursion app are shown on the following overhead
Functionally all that happens when you click the button is counting down to 0 recursively It happens so fast there’s nothing visible on the screen except the result

7

8 The OneButtonRecursion app will be presented in the order in which it was developed:
1. activity_main.xml, the layout 2. strings.xml, the resources 3. A look at R.java, the resources as made available by the system 4. MainActivity.java, the code for the app

9 As you might guess, part of what makes the app interesting is the fact that it includes recursion
It does something so simple that the recursion, although not necessary, is easy to understand Recursion is covered because it will be used in the implementation of Wari in the assignment The recursion introduces the possibility of certain kinds of runtime errors

10 This example also has some things in common with the earlier assignments
It includes syntax for converting between strings and numbers, which can also lead to errors if not done correctly These errors are runtime errors, so they are something else which leads to the topic of debugging in Android

11 activity_main.xml for OneButtonRecursion
The app uses a RelativeLayout It contains a button and a text view The XML code for the layout is given on the following overheads for reference

12 <RelativeLayout xmlns:android="http://schemas. android
xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" >

13 <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:onClick="sendMessage" />

14 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>

15 There were some items in the XML that haven’t come up before
Where did they come from? I used the graphical tools to drag and drop components into the layout

16 The system generated the corresponding XML
Basically, what you’re seeing are some of the parameters that determine the relative position of widgets in a relative layout As always, if you use the graphical layout tools, you can then edit the system generated XML to tailor the layout to the specific app you’re trying to create

17 strings.xml for OneButtonRecursion
The strings.xml file for the app is shown on the following overhead There are no surprises The button and the text view have string resources associated with them

18 <?xml version="1.0" encoding="utf-8"?>
<resources> <string name="app_name">One Button Recursion</string> <string name="action_settings">Settings</string> <string name="button1Contents">Button1</string> <string name="textView1Contents">4</string> </resources>

19 R.Java for OneButtonRecursion
As you recall, the R.java file is generated for you It’s important because it’s the place where you can access resources when writing the Java code for MainActivity The relevant parts of R.java are shown on the following overhead

20 public static final class id {
public static final int button1=0x7f080000; public static final int textView1=0x7f080001; } public static final class string { public static final int button1Contents=0x7f050003; public static final int textView1Contents=0x7f050004;

21 MainActivity.java for OneButtonRecursion, Discussion
The logic of OneButtonRecursion is quite simple The TextView is initially set to a value of 4 When you click the button, you call sendMessage()

22 sendMessage() checks to see what the current value is
If the value is >0, then a call is made to a method named playNextCup() and the value is passed in

23 playNextCup() decrements the value
It updates the text area to this new value If the value has not yet reached 0, it calls itself recursively The end result of this sequence of actions is that the value in the text view goes 4, 3, 2, 1, 0—too fast for the eye to see One click of the button causes the text view to go from 4 to 0, recursively

24 The logic of counting down recursively is relatively simple
The Java implementation that will be shown includes two elements which are not actually necessary to accomplish this task

25 1. It repeatedly gets a handle on the text view and passes this around, even though there is only one text area 2. It includes an if statement to check which button was clicked, even though there is only one button

26 These elements are included here as a preview of the Wari implementation
Wari will have >1 text view and >1 button In that situation it will be necessary to repeatedly get references and pass them around and check which button was clicked

27 Having seen these two elements in the simple example, they will not be an issue in the more complicated example When considering the Wari implementation code it will be possible to focus on additional complexities which it introduces

28 MainActivity.java for OneButtonRecursion, Code
At the top of the main activity the Log class is imported and the TAG string definition is given Notice how the definition of the TAG is similar to the definition of the EXTRA_MESSAGE in the echoing app The Log class will be used for console output when debugging The TAG is just a constant string that will be used when logging output

29 import android.util.Log;
public class MainActivity extends Activity { private static final String TAG = "OneButtonRecursion";

30 sendMessage() for OneButtonRecursion
The code for sendMessage() is shown on the following overhead Notice that the calls to findViewById() and playNextCup() are floating in space They are calls on the MainActivity itself

31 public void sendMessage(View view) {
Button clickedButton = (Button) view; if(clickedButton == findViewById(R.id.button1)) { TextView cup = (TextView) findViewById(R.id.textView1); int handFull = Integer.parseInt(cup.getText().toString()); if(handFull > 0) cup.setText(handFull + ""); playNextCup(cup, handFull); } else

32 playNextCup() for OneButtonRecursion
playNextCup() is the recursive method It contains the uses of Log and TAG (because when you’re doing the recursion it’s a likely place to make a mistake…) Using them for debugging will be discussed shortly

33 public static void playNextCup(TextView cupIn, int handFullIn)
{ handFullIn--; cupIn.setText(handFullIn + ""); if(handFullIn != 0) playNextCup(cupIn, handFullIn); Log.i(TAG, "In recursion " + handFullIn); } else

34 7.2 Unhelpful Error Messages

35 When writing the code even for this simple app, I made mistakes (go figure)
It quickly became apparent that I would need to be able to debug in the Android environment I’m not referring now to the debugging tools in Android Studio—they’re beyond the scope of this course I’m referring to simply figuring out what was going on

36 Compiler Error Messages
Compiler errors are shown in the bottom window of the development environment The screen shot on the following overhead illustrates: How a bad line of code is highlighted in the editor And how the error messages are shown at the bottom

37

38 Line Numbers First helpful hint for debugging in Android Studio:
If you right click on the mouse with the pointer near the left hand margin of the editor, you have the option of showing line numbers in the source This can be very helpful It’s illustrated in the screen shots on the following overheads

39

40

41 An Example of a Runtime Error
Runtime errors can leave you in a quandary How do you figure out what went wrong? As usual, like with many systems, the error messages might not be very helpful

42 Being able to look the error message up on the Web can be very helpful in trying to figure out what it means Do not be afraid to do this I find that stackoverflow.com is the likeliest place to find correct answers (after potentially sorting through things that don’t apply)

43 An error that caused runtime problems with OneButtonRecursion is presented below
I realized that I would need to be able to log output in order to figure out what was going on

44 Here is the snippet of code that’s in error:
int handFull = Integer.parseInt(cup.getText().toString()); cup.setText(handFull); The next overhead shows what happens when you try to run it This is not very helpful

45

46 The error message gives no clue as to why the app stopped
It doesn’t identify the line number in the code where it stopped

47 It turns out that this is the line of code that’s the problem
It assumes that handFull gets converted to a String automatically cup.setText(handFull); This is not the case

48 It is a potentially confusing error
If you look up setText() in the API, there is a version which accepts an integer parameter, where the integer is the id for a resource The value contained in handFull doesn’t agree with any defined resource id value, so the system has a runtime problem

49 Imagine the fun you’d have if, by accident, handFull did contain a valid resource id, and you got inexplicable results instead of a runtime error

50 Once you know what’s wrong, in this example the solution is simple
Turn the parameter into a String This is the corrected code: int handFull = Integer.parseInt(cup.getText().toString()); cup.setText(handFull + “”);

51 Keep in mind that in this snippet of code, problems can also arise in the first line
int handFull = Integer.parseInt(cup.getText().toString()); cup.setText(handFull + “”); parseInt() will fail if you apply it to a string that can’t be parsed as an integer

52 This motivates the idea that it’s useful to be able to identify the line of code where execution stopped There are multiple places where failure might have occurred You would like to figure out where, so that you can fix the problem

53 7.3 Logging Output

54 The playNext() method contained calls to the static method i() in the Log class which causes the code to generate runtime output i() is not the most descriptive method name It apparently stands for “information” The code with logging is shown on the following overhead

55 public static void playNextCup(TextView cupIn, int handFullIn) { handFullIn--; cupIn.setText(handFullIn + ""); if(handFullIn != 0) { playNextCup(cupIn, handFullIn); Log.i(TAG, "In recursion " + handFullIn); } else { } }

56 The screen shot on the following overhead shows the logcat screen open at the bottom of the development environment after OneButtonRecursion has been run The highlighted lines are the output of the program, showing the succession of values generated by the recursion and put out by the call to Log.i()

57

58 In order to do simple debugging, you need to be able to print output strings from your code, like calling System.out.println() in Java code The Android system will write to LogCat The programmer can also send non-graphical output there

59 These are the lines of code in the application related to logging
import android.util.Log; public class MainActivity extends Activity { private static final String TAG = "OneButtonRecursion"; Log.i(TAG, "In recursion " + handFullIn);

60 In order to write to LogCat you need to import the Log class
Log contains static methods, like i() These log methods take two strings as parameters, a tag, and the actual output It’s simplest to just define a TAG up front so that every line from a given app is clearly identified in the LogCat

61 Then at strategic places put calls to Log.i() to see what’s happening
Android Studio has fancier debugging tools, but sending output to LogCat is straightforward and doesn’t require learning anything more about Android Studio

62 An Example The following overhead shows a block of code with a parseInt() call As mentioned, if the parameter can’t be parsed, this will fail

63 TextView capturedCup = (TextView) activityIn. findViewById(R. id
TextView capturedCup = (TextView) activityIn.findViewById(R.id.textView16); int capturedCount = Integer.parseInt(capturedCup.getText().toString()); capturedCount += seedCount; capturedCup.setText(capturedCount + "");

64 The runtime error message generated by a failed parseInt() call will not be very helpful
The error message will not tell you which line of code caused the runtime error The code on the overhead following the next one shows how to identify the line where the problem occurred

65 The technique is to simply call Log.i() after every line of code
When the app stops, it will generate the unhelpful runtime error message You can then look in LogCat and see which line of code was the last one to run successfully This is indicated by the last Log.i() statement which generated output

66 /* Debugging code */ /* Log.i(TAG, "1"); TextView capturedCup = (TextView) activityIn.findViewById(R.id.textView16); Log.i(TAG, "2, capturedCup id: " + capturedCup); CharSequence tempText = capturedCup.getText(); Log.i(TAG, "3"); String tempString = tempText.toString(); Log.i(TAG, "4, tempString contents of capturedCup: " + tempString); int capturedCount = Integer.parseInt(tempString); Log.i(TAG, "5"); capturedCount += seedCount; Log.i(TAG, "6"); capturedCup.setText("x"); //(capturedCount + ""); Log.i(TAG, "7"); */

67 Summary and Mission Getting OneButtonRecursion to work is part of your assignment Admittedly, this is largely a matter of cutting and pasting from the overheads into Android Studio

68 Even though it’s simple, it’s a worthwhile exercise, assuming you pay attention to the code as you go and familiarize yourself with how it works You will turn this in at the same time as the rest of the assignment

69 The End


Download ppt "Android 7: One Button Recursion and Debugging"

Similar presentations


Ads by Google