Merge "Delete more navcache stuff"
diff --git a/api/current.txt b/api/current.txt
index 3fa7ad9..13d3228 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15326,6 +15326,7 @@
method public android.os.StrictMode.VmPolicy.Builder detectActivityLeaks();
method public android.os.StrictMode.VmPolicy.Builder detectAll();
method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
+ method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
method public android.os.StrictMode.VmPolicy.Builder penaltyDeath();
method public android.os.StrictMode.VmPolicy.Builder penaltyDropBox();
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index d9bbb4a..de9470e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -512,6 +512,7 @@
public void removeContextRegistrations(Context context,
String who, String what) {
+ final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
mReceivers.remove(context);
if (rmap != null) {
@@ -525,6 +526,9 @@
"call to unregisterReceiver()?");
leak.setStackTrace(rd.getLocation().getStackTrace());
Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
+ if (reportRegistrationLeaks) {
+ StrictMode.onIntentReceiverLeaked(leak);
+ }
try {
ActivityManagerNative.getDefault().unregisterReceiver(
rd.getIIntentReceiver());
@@ -546,6 +550,9 @@
+ sd.getServiceConnection() + " that was originally bound here");
leak.setStackTrace(sd.getLocation().getStackTrace());
Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
+ if (reportRegistrationLeaks) {
+ StrictMode.onServiceConnectionLeaked(leak);
+ }
try {
ActivityManagerNative.getDefault().unbindService(
sd.getIServiceConnection());
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 99f58a0..a0ad9c0 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -20,7 +20,10 @@
import android.app.ActivityThread;
import android.app.ApplicationErrorReport;
import android.app.IActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.util.Log;
import android.util.Printer;
import android.util.Singleton;
@@ -195,9 +198,15 @@
*/
private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000; // for VmPolicy
+ /**
+ * @hide
+ */
+ public static final int DETECT_VM_REGISTRATION_LEAKS = 0x2000; // for VmPolicy
+
private static final int ALL_VM_DETECT_BITS =
DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
- DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS;
+ DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS |
+ DETECT_VM_REGISTRATION_LEAKS;
/**
* @hide
@@ -618,8 +627,8 @@
* but will likely expand in future releases.
*/
public Builder detectAll() {
- return enable(DETECT_VM_ACTIVITY_LEAKS |
- DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS);
+ return enable(DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS
+ | DETECT_VM_CLOSABLE_LEAKS | DETECT_VM_REGISTRATION_LEAKS);
}
/**
@@ -648,6 +657,15 @@
}
/**
+ * Detect when a {@link BroadcastReceiver} or
+ * {@link ServiceConnection} is leaked during {@link Context}
+ * teardown.
+ */
+ public Builder detectLeakedRegistrationObjects() {
+ return enable(DETECT_VM_REGISTRATION_LEAKS);
+ }
+
+ /**
* Crashes the whole process on violation. This penalty runs at
* the end of all enabled penalties so yo you'll still get
* your logging or other violations before the process dies.
@@ -1499,6 +1517,13 @@
/**
* @hide
*/
+ public static boolean vmRegistrationLeaksEnabled() {
+ return (sVmPolicyMask & DETECT_VM_REGISTRATION_LEAKS) != 0;
+ }
+
+ /**
+ * @hide
+ */
public static void onSqliteObjectLeaked(String message, Throwable originStack) {
onVmPolicyViolation(message, originStack);
}
@@ -1510,6 +1535,20 @@
onVmPolicyViolation(null, originStack);
}
+ /**
+ * @hide
+ */
+ public static void onIntentReceiverLeaked(Throwable originStack) {
+ onVmPolicyViolation(null, originStack);
+ }
+
+ /**
+ * @hide
+ */
+ public static void onServiceConnectionLeaked(Throwable originStack) {
+ onVmPolicyViolation(null, originStack);
+ }
+
// Map from VM violation fingerprint to uptime millis.
private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>();
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 9628d6b..3c0ee12 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -34,8 +34,8 @@
import java.util.HashMap;
/**
- * This class is used to instantiate layout XML file into its corresponding View
- * objects. It is never be used directly -- use
+ * Instantiates a layout XML file into its corresponding {@link android.view.View}
+ * objects. It is never used directly. Instead, use
* {@link android.app.Activity#getLayoutInflater()} or
* {@link Context#getSystemService} to retrieve a standard LayoutInflater instance
* that is already hooked up to the current context and correctly configured
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 62afd61..55acb74 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1217,7 +1217,7 @@
/**
* Equivalent to calling ImageView.setImageBitmap
*
- * @param viewId The id of the view whose drawable should change
+ * @param viewId The id of the view whose bitmap should change
* @param bitmap The new Bitmap for the drawable
*/
public void setImageViewBitmap(int viewId, Bitmap bitmap) {
@@ -1240,7 +1240,7 @@
* and {@link Chronometer#start Chronometer.start()} or
* {@link Chronometer#stop Chronometer.stop()}.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the {@link Chronometer} to change
* @param base The time at which the timer would have read 0:00. This
* time should be based off of
* {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
@@ -1261,7 +1261,7 @@
*
* If indeterminate is true, then the values for max and progress are ignored.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the {@link ProgressBar} to change
* @param max The 100% value for the progress bar
* @param progress The current value of the progress bar.
* @param indeterminate True if the progress bar is indeterminate,
@@ -1367,7 +1367,7 @@
/**
* Equivalent to calling {@link android.widget.TextView#setTextColor(int)}.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view whose text color should change
* @param color Sets the text color for all the states (normal, selected,
* focused) to be this color.
*/
@@ -1380,7 +1380,7 @@
*
* @param appWidgetId The id of the app widget which contains the specified view. (This
* parameter is ignored in this deprecated method)
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the {@link AbsListView}
* @param intent The intent of the service which will be
* providing data to the RemoteViewsAdapter
* @deprecated This method has been deprecated. See
@@ -1395,7 +1395,7 @@
* Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
* Can only be used for App Widgets.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the {@link AbsListView}
* @param intent The intent of the service which will be
* providing data to the RemoteViewsAdapter
*/
@@ -1406,7 +1406,7 @@
/**
* Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view to change
* @param position Scroll to this adapter position
*/
public void setScrollPosition(int viewId, int position) {
@@ -1416,7 +1416,7 @@
/**
* Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view to change
* @param offset Scroll by this adapter position offset
*/
public void setRelativeScrollPosition(int viewId, int offset) {
@@ -1426,7 +1426,7 @@
/**
* Call a method taking one boolean on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1437,7 +1437,7 @@
/**
* Call a method taking one byte on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1448,7 +1448,7 @@
/**
* Call a method taking one short on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1459,7 +1459,7 @@
/**
* Call a method taking one int on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1470,7 +1470,7 @@
/**
* Call a method taking one long on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1481,7 +1481,7 @@
/**
* Call a method taking one float on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1492,7 +1492,7 @@
/**
* Call a method taking one double on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1503,7 +1503,7 @@
/**
* Call a method taking one char on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1514,7 +1514,7 @@
/**
* Call a method taking one String on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1525,7 +1525,7 @@
/**
* Call a method taking one CharSequence on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1536,7 +1536,7 @@
/**
* Call a method taking one Uri on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1550,7 +1550,7 @@
* <p class="note">The bitmap will be flattened into the parcel if this object is
* sent across processes, so it may end up using a lot of memory, and may be fairly slow.</p>
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1561,7 +1561,7 @@
/**
* Call a method taking one Bundle on a view in the layout for this RemoteViews.
*
- * @param viewId The id of the view whose text should change
+ * @param viewId The id of the view on which to call the method.
* @param methodName The name of the method to call.
* @param value The value to pass to the method.
*/
@@ -1570,10 +1570,11 @@
}
/**
+ * Call a method taking one Intent on a view in the layout for this RemoteViews.
*
- * @param viewId
- * @param methodName
- * @param value
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param value The {@link android.content.Intent} to pass the method.
*/
public void setIntent(int viewId, String methodName, Intent value) {
addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INTENT, value));
diff --git a/docs/html/guide/developing/devices/emulator.jd b/docs/html/guide/developing/devices/emulator.jd
index 02dcb68..c217790 100644
--- a/docs/html/guide/developing/devices/emulator.jd
+++ b/docs/html/guide/developing/devices/emulator.jd
@@ -78,7 +78,7 @@
applications. You can choose what version of the Android system you want to
run in the emulator by configuring AVDs, and you can also customize the
mobile device skin and key mappings. When launching the emulator and at runtime,
-you can use a variety of commands and options to control the its behaviors.
+you can use a variety of commands and options to control its behavior.
</p>
<p>The Android system image distributed in the SDK contains ARM machine code for
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index 5151ec1..09e41c3 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -516,7 +516,7 @@
</tr>
<tr>
<td>Audio volume up button</td>
- <td>KEYPAD_PLUS, Ctrl-5</td>
+ <td>KEYPAD_PLUS, Ctrl-F5</td>
</tr>
<tr>
diff --git a/docs/html/guide/topics/fundamentals/activities.jd b/docs/html/guide/topics/fundamentals/activities.jd
index 8736aa8..b79136c 100644
--- a/docs/html/guide/topics/fundamentals/activities.jd
+++ b/docs/html/guide/topics/fundamentals/activities.jd
@@ -62,7 +62,7 @@
activity can then start another activity in order to perform different actions. Each time a new
activity starts, the previous activity is stopped, but the system preserves the activity
in a stack (the "back stack"). When a new activity starts, it is pushed onto the back stack and
-takes user focus. The back stack abides to the basic "last in, first out" queue mechanism,
+takes user focus. The back stack abides to the basic "last in, first out" stack mechanism,
so, when the user is done with the current activity and presses the <em>Back</em> button, it
is popped from the stack (and destroyed) and the previous activity resumes. (The back stack is
discussed more in the <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks
diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd
index 281cb9d..2a22394 100644
--- a/docs/html/guide/topics/fundamentals/fragments.jd
+++ b/docs/html/guide/topics/fundamentals/fragments.jd
@@ -129,7 +129,7 @@
<p>For example—to continue with the news application example—the application can embed
two fragments in <em>Activity A</em>, when running on a tablet-sized device. However, on a
-handset-sized screen, there's not be enough room for both fragments, so <em>Activity A</em> includes
+handset-sized screen, there's not enough room for both fragments, so <em>Activity A</em> includes
only the fragment for the list of articles, and when the user selects an article, it starts
<em>Activity B</em>, which includes the second fragment to read the article. Thus, the application
supports both tablets and handsets by reusing fragments in different combinations, as illustrated in
diff --git a/docs/html/guide/topics/wireless/bluetooth.jd b/docs/html/guide/topics/wireless/bluetooth.jd
index 76da08e..0567799 100644
--- a/docs/html/guide/topics/wireless/bluetooth.jd
+++ b/docs/html/guide/topics/wireless/bluetooth.jd
@@ -249,12 +249,20 @@
<p>A dialog will appear requesting user permission to enable Bluetooth, as shown
in Figure 1. If the user responds "Yes," the system will begin to enable Bluetooth
and focus will return to your application once the process completes (or fails).</p>
-<p>If enabling Bluetooth succeeds, your Activity will receive the {@link
+
+<p>The {@code REQUEST_ENABLE_BT} constant passed to {@link
+android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} is a locally
+defined integer (which must be greater than 0), that the system passes back to you in your
+{@link
+android.app.Activity#onActivityResult(int,int,Intent) onActivityResult()} implementation as the
+<code>requestCode</code> parameter.</p>
+
+<p>If enabling Bluetooth succeeds, your activity receives the {@link
android.app.Activity#RESULT_OK} result code in the {@link
android.app.Activity#onActivityResult(int,int,Intent) onActivityResult()}
callback. If Bluetooth was not enabled
-due to an error (or the user responded "No") then the result code will be {@link
-android.app.Activity#RESULT_CANCELED}.</p>
+due to an error (or the user responded "No") then the result code is {@link
+android.app.Activity#RESULT_CANCELED}.</p>
</li>
</ol>
@@ -431,11 +439,11 @@
<p>A dialog will be displayed, requesting user permission to make the device
discoverable, as shown in Figure 2. If the user responds "Yes," then the device
-will become discoverable for the specified amount of time. Your Activity will
+will become discoverable for the specified amount of time. Your activity will
then receive a call to the {@link android.app.Activity#onActivityResult(int,int,Intent)
onActivityResult())} callback, with the result code equal to the duration that the device
is discoverable. If the user responded "No" or if an error occurred, the result code will
-be Activity.RESULT_CANCELLED.</p>
+be {@link android.app.Activity#RESULT_CANCELED}.</p>
<p class="note"><strong>Note:</strong> If Bluetooth has not been enabled on the device,
then enabling device discoverability will automatically enable Bluetooth.</p>
@@ -568,7 +576,7 @@
</ol>
<p>The {@link android.bluetooth.BluetoothServerSocket#accept()} call should not
-be executed in the main Activity UI thread because it is a blocking call and
+be executed in the main activity UI thread because it is a blocking call and
will prevent any other interaction with the application. It usually makes
sense to do all work with a {@link android.bluetooth.BluetoothServerSocket} or {@link
android.bluetooth.BluetoothSocket} in a new
@@ -696,7 +704,7 @@
12 seconds), then it will throw an exception.</p>
<p>Because {@link
android.bluetooth.BluetoothSocket#connect()} is a blocking call, this connection
-procedure should always be performed in a thread separate from the main Activity
+procedure should always be performed in a thread separate from the main activity
thread.</p>
<p class="note">Note: You should always ensure that the device is not performing
device discovery when you call {@link
@@ -838,7 +846,7 @@
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
- // Send the obtained bytes to the UI Activity
+ // Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
@@ -847,14 +855,14 @@
}
}
- /* Call this from the main Activity to send data to the remote device */
+ /* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
- /* Call this from the main Activity to shutdown the connection */
+ /* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
@@ -866,12 +874,12 @@
<p>The constructor acquires the necessary streams and once executed, the thread
will wait for data to come through the InputStream. When {@link
java.io.InputStream#read(byte[])} returns with
-bytes from the stream, the data is sent to the main Activity using a member
+bytes from the stream, the data is sent to the main activity using a member
Handler from the parent class. Then it goes back and waits for more bytes from
the stream.</p>
<p>Sending outgoing data is as simple as calling the thread's
-<code>write()</code> method from the main Activity and passing in the bytes to
+<code>write()</code> method from the main activity and passing in the bytes to
be sent. This method then simply calls {@link
java.io.OutputStream#write(byte[])} to send the data to the remote device.</p>
diff --git a/docs/html/resources/tutorials/notepad/notepad-ex2.jd b/docs/html/resources/tutorials/notepad/notepad-ex2.jd
index ed06778..1334d7a 100644
--- a/docs/html/resources/tutorials/notepad/notepad-ex2.jd
+++ b/docs/html/resources/tutorials/notepad/notepad-ex2.jd
@@ -87,7 +87,7 @@
menu callback used for the options menu. Here, we add just one line, which will add a menu item
to delete a note. Call <code>menu.add()</code> like so:
<pre>
-public void onCreateContextMenu(Menu menu, View v, ContextMenuInfo menuInfo) {
+public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}</pre>
diff --git a/docs/html/resources/tutorials/views/hello-formstuff.jd b/docs/html/resources/tutorials/views/hello-formstuff.jd
index b9f6c16..1ddd1df 100644
--- a/docs/html/resources/tutorials/views/hello-formstuff.jd
+++ b/docs/html/resources/tutorials/views/hello-formstuff.jd
@@ -91,31 +91,30 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
- android:background="@drawable/android_button" />
+ android:background="@drawable/android_button"
+ android:onClick="onButtonClicked"/>
</pre>
<p>The <code>android:background</code> attribute specifies the drawable resource to use for the
button background (which, when saved at <code>res/drawable/android.xml</code>, is
referenced as <code>@drawable/android</code>). This replaces the normal background image
-used for buttons throughout the system. In order for the drawable to change its image based on
-the button state, the image must be applied to the background.</p>
+applied by the system with the drawable created above, which changes its image based on
+the button state.</p>
+ <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity
+that the system should call when the user clicks the button. You'll create that method next.</p>
</li>
<li>To make the button do something when pressed, add the following
-code at the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
+method inside your {@link android.app.Activity} class:
<pre>
-final Button button = (Button) findViewById(R.id.button);
-button.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- // Perform action on clicks
- Toast.makeText(HelloFormStuff.this, "Beep Bop", Toast.LENGTH_SHORT).show();
- }
-});
+public void onButtonClicked(View v) {
+ // Do something when the button is clicked
+ Toast.makeText(HelloFormStuff.this, "Button clicked", Toast.LENGTH_SHORT).show();
+}
</pre>
-<p>This captures the {@link android.widget.Button} from the layout, then adds an {@link
-android.view.View.OnClickListener}. The {@link android.view.View.OnClickListener}
-must implement the {@link android.view.View.OnClickListener#onClick(View)} callback method, which
-defines the action to be made when the button is clicked. In this example, a
-{@link android.widget.Toast} message will be displayed.</p>
+<p>When you specify this kind of method, which is used in your layout file with the {@code
+android:onClick} attribute, the method must be <code>public</code>, have a <code>void</code> return
+value, and accept a single {@code android.view.View} parameter. When the system calls this method,
+it passes the {@code android.view.View} that was clicked.</p>
</li>
<li>Now run the application.</li>
</ol>
@@ -183,34 +182,33 @@
<CheckBox android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="check it out" />
+ android:text="check it out"
+ android:onClick="onCheckboxClicked"/>
</pre>
+ <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity
+that the system should call when the user clicks the check box. You'll create that method next.</p>
</li>
-<li>To do something when the state is changed, add the following code
-to the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
+<li>To do something when the state is changed, add the following method inside your {@link
+android.app.Activity} class:</p>
+
<pre>
-final CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox);
-checkbox.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- // Perform action on clicks, depending on whether it's now checked
- if (((CheckBox) v).isChecked()) {
- Toast.makeText(HelloFormStuff.this, "Selected", Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(HelloFormStuff.this, "Not selected", Toast.LENGTH_SHORT).show();
- }
+public void onCheckboxClicked(View v) {
+ // Perform action on clicks, depending on whether it's now checked
+ if (((CheckBox) v).isChecked()) {
+ Toast.makeText(HelloFormStuff.this, "Selected", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(HelloFormStuff.this, "Not selected", Toast.LENGTH_SHORT).show();
}
-});
+}
</pre>
-<p>This captures the {@link android.widget.CheckBox} element from the layout, then adds an {@link
-android.view.View.OnClickListener}. The {@link android.view.View.OnClickListener} must implement the
-{@link android.view.View.OnClickListener#onClick(View)} callback method, which
-defines the action to be made when the checkbox is clicked. When clicked, {@link
-android.widget.CompoundButton#isChecked()} is called to check the new state of the check box. If it
-has been checked, then a {@link android.widget.Toast} displays the message "Selected", otherwise it
-displays "Not selected". Note that the {@link android.view.View} object that is passed in the {@link
-android.view.View.OnClickListener#onClick(View)} callback must be cast to a {@link
-android.widget.CheckBox} because the {@link android.widget.CompoundButton#isChecked()} method is
-not defined by the parent {@link android.view.View} class. The {@link android.widget.CheckBox}
+
+<p>When you specify this kind of method, which is used in your layout file with the {@code
+android:onClick}
+attribute, the method must be <code>public</code>, have a <code>void</code> return value, and
+accept a single {@code android.view.View} parameter. When the system calls this method, it
+passes the {@code android.view.View} that was clicked. In this example, the {@code
+android.view.View} is cast to a {@link android.widget.CheckBox} to determine whether the widget
+has been checked or unchecked. The {@link android.widget.CheckBox} widget
handles its own state changes, so you only need to query the current state.</p>
</li>
<li>Run it.</li>
@@ -240,44 +238,44 @@
<RadioButton android:id="@+id/radio_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Red" />
+ android:text="Red"
+ android:onClick="onRadioButtonClicked"/>
<RadioButton android:id="@+id/radio_blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Blue" />
+ android:text="Blue"
+ android:onClick="onRadioButtonClicked"/>
</RadioGroup>
</pre>
<p>It's important that the {@link android.widget.RadioButton}s are grouped together by the {@link
android.widget.RadioGroup} element so that no more than one can be selected at a time. This logic
is automatically handled by the Android system. When one {@link android.widget.RadioButton} within
a group is selected, all others are automatically deselected.</p>
+ <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity
+that the system should call when the user clicks the radio button. You'll create that method
+next.</p>
</li>
-<li>To do something when each {@link android.widget.RadioButton} is selected, you need an
-{@link android.view.View.OnClickListener}. In this case, you want the listener to be re-usable, so
-add the following code to create a new member in the <code>HelloFormStuff</code> Activity:
+<li>To do something when each {@link android.widget.RadioButton} is selected, add the following
+method inside your {@link android.app.Activity} class:</p>
+
<pre>
-private OnClickListener radio_listener = new OnClickListener() {
- public void onClick(View v) {
- // Perform action on clicks
- RadioButton rb = (RadioButton) v;
- Toast.makeText(HelloFormStuff.this, rb.getText(), Toast.LENGTH_SHORT).show();
- }
-};
+public void onRadioButtonClicked(View v) {
+ // Perform action on clicks
+ RadioButton rb = (RadioButton) v;
+ Toast.makeText(HelloFormStuff.this, rb.getText(), Toast.LENGTH_SHORT).show();
+}
</pre>
-<p>First, the {@link android.view.View} that is passed to the {@link
-android.view.View.OnClickListener#onClick(View)} method is cast into a RadioButton. Then a
-{@link android.widget.Toast} message displays the selected radio button's text.</p>
-<li>Now, at the bottom of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method, add
-the following:
-<pre>
- final RadioButton radio_red = (RadioButton) findViewById(R.id.radio_red);
- final RadioButton radio_blue = (RadioButton) findViewById(R.id.radio_blue);
- radio_red.setOnClickListener(radio_listener);
- radio_blue.setOnClickListener(radio_listener);
-</pre>
-<p>This captures each of the {@link android.widget.RadioButton}s from the layout and adds the
-newly-created {@link android.view.View.OnClickListener} to each.</p>
+
+<p>When you specify this kind of method, which is used in your layout file with the {@code
+android:onClick}
+attribute, the method must be <code>public</code>, have a <code>void</code> return value, and
+accept a single {@code android.view.View} parameter. When the system calls this method, it
+passes the {@code android.view.View} that was clicked.</p>
+<p>Because each {@link android.widget.RadioButton} widget is grouped into a {@link
+android.widget.RadioGroup}, each widget handles its own state changes when a new button is
+selected.</p>
+</li>
<li>Run the application.</li>
</ol>
@@ -303,31 +301,35 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Vibrate on"
- android:textOff="Vibrate off"/>
+ android:textOff="Vibrate off"
+ android:onClick="onToggleClicked"/>
</pre>
<p>The attributes <code>android:textOn</code> and <code>android:textOff</code> specify the text
for the button when the button has been toggled on or off. The default values are "ON" and
"OFF".</p>
+ <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity
+that the system should call when the user clicks the button. You'll create that method next.</p>
</li>
-<li>To do something when the state is changed, add the following code
-to the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
+<li>To do something when the user clicks the button, add the following
+method inside your {@link android.app.Activity} class:</p>
+
<pre>
-final ToggleButton togglebutton = (ToggleButton) findViewById(R.id.togglebutton);
-togglebutton.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- // Perform action on clicks
- if (togglebutton.isChecked()) {
- Toast.makeText(HelloFormStuff.this, "Checked", Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(HelloFormStuff.this, "Not checked", Toast.LENGTH_SHORT).show();
- }
+public void onToggleClicked(View v) {
+ // Perform action on clicks
+ if (((ToggleButton) v).isChecked()) {
+ Toast.makeText(HelloFormStuff.this, "Toggle on", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(HelloFormStuff.this, "Toggle off", Toast.LENGTH_SHORT).show();
}
-});
+}
</pre>
-<p>This captures the {@link android.widget.ToggleButton} element from the layout, then adds an
-{@link android.view.View.OnClickListener}. The {@link android.view.View.OnClickListener} must
-implement the {@link android.view.View.OnClickListener#onClick(View)} callback method, which
-defines the action to perform when the button is clicked. In this example, the callback
+
+<p>When you specify this kind of method, which is used in your layout file with the {@code
+android:onClick}
+attribute, the method must be <code>public</code>, have a <code>void</code> return value, and
+accept a single {@code android.view.View} parameter. When the system calls this method, it
+passes the {@code android.view.View} that was clicked.</p>
+<p>In this example, the callback
method checks the new state of the button, then shows a {@link android.widget.Toast} message that
indicates the current state.</p>
diff --git a/docs/html/resources/tutorials/views/hello-mapview.jd b/docs/html/resources/tutorials/views/hello-mapview.jd
index ac5e826..7a0bedf 100644
--- a/docs/html/resources/tutorials/views/hello-mapview.jd
+++ b/docs/html/resources/tutorials/views/hello-mapview.jd
@@ -208,7 +208,7 @@
new class constructor:
<pre>
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
- super(defaultMarker);
+ super(boundCenterBottom(defaultMarker));
mContext = context;
}
</pre>