1 / 104

Android 5: Wari

Android 5: Wari. Introduction. This set of overheads is more than just Wari It 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

lainey
Download Presentation

Android 5: Wari

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Android 5: Wari

  2. Introduction • This set of overheads is more than just Wari • It 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 • It is also a lead-in to the code for Wari

  3. Wari illustrates both code logic and a more complicated layout • There are two perspectives on what’s going on: • First of all, it should be apparent that things are easier because GUI layout work is separate from the Java code • On the other hand, in order to deal with this separation between logic and layout, the implementation of Wari will differ significatly from implementations you’ve seen before

  4. 5.1 The OneButtonRecursion app • 5.2 Unhelpful Error Messages • 5.3 Logging Output • 5.4 Wari—General Remarks • 5.5 layout.xml for Wari • 5.6 strings.xml for Wari • 5.7 R.java for Wari • 5.8 MainActivity.java for Wari

  5. 5.1 The OneButtonRecursionapp • 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. Look at R.java, the resources as made available by the system • 4. MainActivity.java, the code for the app

  6. As you might guess, part of what makes the app interesting is the fact that it includes recursion • This is a preview of the fact that recursion will be used in the implementation of Wari

  7. The other thing that makes the app interesting, and relevant to Wari, is that the contents of the text view are changeable, and are treated as an integer • This introduces some syntax, which in turn, introduces the possibility of errors • These errors turn out to be runtime errors, so it behooves us to consider the topic of debugging in Android

  8. activity_main.xml for OneButtonRecursion • A screenshot of the layout of the OneButtonRecursion app in the development environment is shown on the following overhead • It is a simple layout, containing a button and a text view

  9. This app happens to use relative layout • There is nothing particularly striking about the syntax for that • The XML code for the layout is given on the following overheads for reference

  10. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" • xmlns:tools="http://schemas.android.com/tools" • android:layout_width="match_parent" • android:layout_height="match_parent" • android:paddingBottom="@dimen/activity_vertical_margin" • android:paddingLeft="@dimen/activity_horizontal_margin" • android:paddingRight="@dimen/activity_horizontal_margin" • android:paddingTop="@dimen/activity_vertical_margin" • tools:context=".MainActivity" >

  11. <Button • android:id="@+id/button1" • style="?android:attr/buttonStyleSmall" • android:layout_width="wrap_content" • android:layout_height="wrap_content" • android:layout_alignParentLeft="true" • android:layout_alignParentTop="true" • android:text="@string/button1Contents" • android:onClick="sendMessage" />

  12. <TextView • android:id="@+id/textView1" • android:layout_width="wrap_content" • android:layout_height="wrap_content" • android:layout_alignBaseline="@+id/button1" • android:layout_alignBottom="@+id/button1" • android:layout_toRightOf="@+id/button1" • android:text="@string/textView1Contents" /> • </RelativeLayout>

  13. 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

  14. <?xml version="1.0" encoding="utf-8"?> • <resources> • <string name="app_name">One Button Recursion</string> • <string name="action_settings">Settings</string> • <string name="hello_world">Hello world!</string> • <string name="button1Contents">Button1</string> • <string name="textView1Contents">4</string> • </resources>

  15. 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

  16. public static final class id { • … • public static final intbutton1=0x7f080000; • public static final inttextView1=0x7f080001; • } • … • } • public static final class string { • … • public static final intbutton1Contents=0x7f050003; • public static final inttextView1Contents=0x7f050004;

  17. MainActivity.java for OneButtonRecursion • 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()

  18. 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

  19. 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

  20. The logic is simple, but the code will look needlessly complex • It repeatedly gets a handle on the text view and passes this around—which is needless, considering there is only one text area • It also includes if statements to check “which button was clicked” when there is only one button

  21. The code is written in this way because it is a preview of what will have to be done to implement Wari • It is clumsy here, but it’s easier to first get an idea of what’s involved in a mindless recursion program with only one text view and one button • Then, in an app with >1 text view and button, it becomes apparent that it is necessary to repeatedly get references and pass them around and check which button was clicked

  22. An Import and a Declaration and Initialization for Debugging • The import and TAG definition shown here will be useful for logging • They come at the beginning of the MainActivity class, so they are shown now • Further explanations will be given later • import android.util.Log; • public class MainActivity extends Activity { • private static final String TAG = "OneButtonRecursion"; • …

  23. sendMessage() for OneButtonRecursion • The code for sendMessage() is shown on the following overhead • Note that the calls to findViewById() and playNextCup() are floating in space • They are calls on the MainActivity itself • The concept of activities is important and will be pursued further in later sets of overheads

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

  25. playNextCup() for OneButtonRecursion • playNextCup() contains the recursive call • It also contains the uses of Log and TAG • These will be explained in a moment

  26. public static void playNextCup(TextViewcupIn, inthandFullIn) • { • handFullIn--; • cupIn.setText(handFullIn+ ""); • if(handFullIn!= 0) • { • playNextCup(cupIn, handFullIn); • Log.i(TAG, "In recursion " + handFullIn); • } • else • { • } • }

  27. 5.2 Unhelpful Error Messages • 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 Eclipse—they’re beyond the scope of this course • I’m referring to simply figuring out what was going on

  28. Compiler errors are shown at the bottom of the screen under the “Problems” tab, and they’re marked in red there and flagged in your code • You will find that Eclipse has a helpful “Quick Fix” tool that frequently tells you pretty clearly what’s wrong and how to fix it • These things are illustrated on the following overhead

  29. I also got two good (bad) examples with OneButtonRecursion of what can go more seriously wrong and the quandary you’re left in • These were runtime errors, and they illustrated two features of the development environment

  30. 1. In Java programming, you may be used to the fact that even runtime errors show the line numbers in your code where the errors occur • This does not appear to be the case with Android • You do see a trace of calls, but it’s up to you to figure out where that trace intersects your code and the exact location of the problem

  31. 2. The second aspect accounts for the heading of this section • Like with many systems, the error messages are not necessarily helpful • As usual, being able to look the error message up on the Web was very helpful in trying to figure out what it meant

  32. Example 1 • Here is a snippet of code that’s in error: • inthandFull = Integer.parseInt(cup.getText().toString()); • … • cup.setText(handFull); • Here is the error message you get: • No package identifier when getting value for resource number HideousHexValue

  33. This is not helpful • It seems to suggest some deep problem with the use of resources (like the values in R.java) or maybe with passing parameters, like the activity, around • It doesn’t identify which method call is the source of the problem

  34. The explanation turns out to be much simpler • When writing the incorrect code, I heedlessly assumed that setText() converted whatever parameter was sent to it to a string by an internal call to toString() • This is not so • There is a version of setText() which accepts an integer parameter, where the integer is the id for a resource

  35. The value contained in handFull doesn’t agree with any defined resource id value, so the system has a runtime problem • (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)

  36. In any case, once you know what’s wrong, the solution is simple • This is the corrected code: • inthandFull = Integer.parseInt(cup.getText().toString()); • … • cup.setText(handFull + “”);

  37. Example 2 • The same two lines of code contain a call that can also generate an unhelpful runtime error • inthandFull = Integer.parseInt(cup.getText().toString()); • … • cup.setText(handFull + “”); • Consider the call to parseInt()

  38. This problem could result anywhere and is the result of carelessness in coding • parseInt() will fail if you apply it to a string that can’t be parsed as an integer • A runtime error can be avoided by careful coding or by putting the call in a try catch block

  39. However, if you write the code as shown • And the text view you’re getting the string from doesn’t contain an integer • You will get this runtime error message: • FATAL EXCEPTION: main java.lang.IllegalStateException • It sounds grievous, doesn’t it?

  40. The tracing of calls that’s presented eventually reaches the parseInt() call, but it’s not immediately apparent what it is about that call that’s causing such a serious problem • The error message obviously doesn’t tell you something simple, like the parameter passed to the method isn’t right • I sorted this out with good, old-fashioned debugging, the subject of the next section

  41. 5.3 Logging Output • A screenshot of the current example is shown on the following overhead • The playNext() method is shown in the editor • The LogCat tab has been selected at the bottom • This shows the non-graphical output of the app

  42. 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);

  43. In short, Log is more or less equivalent to System.out in Java • You need to import the Log file • The methods on log are like “i”, which stands for “information” (as opposed to println() for System.out) • These log methods take two strings as parameters, a tag, and the actual output

  44. It’s simplest to just define a TAG so that every line from a given app is clearly identified in the LogCat • Then at strategic places put calls to Log.i() to see what’s happening • Eclipse has fancier debugging tools, but I’ve always done it by hand in this way

  45. An Example • On the following overhead is a block of code that gave me a runtime error • As noted earlier, the runtime error messages are not always as helpful as they might be • I couldn’t tell what exactly was wrong

  46. TextViewcapturedCup = (TextView) activityIn.findViewById(R.id.textView16); • intcapturedCount = Integer.parseInt(capturedCup.getText().toString()); • capturedCount += seedCount; • capturedCup.setText(capturedCount + "");

More Related