Skip to content

Commit 871a6d7

Browse files
Justin HoAndroid (Google) Code Review
authored andcommitted
Merge "Revert "This restores JB MR0 behavior where the framework throws an exception for improper layouts that are missing layout_width and/or layout_height."" into jb-mr1-dev
2 parents 4db3165 + 4e360f0 commit 871a6d7

File tree

8 files changed

+74
-106
lines changed

8 files changed

+74
-106
lines changed

api/current.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7094,7 +7094,7 @@ package android.content.res {
70947094
method public int getIndexCount();
70957095
method public int getInt(int, int);
70967096
method public int getInteger(int, int);
7097-
method public int getLayoutDimension(int, java.lang.String);
7097+
method public deprecated int getLayoutDimension(int, java.lang.String);
70987098
method public int getLayoutDimension(int, int);
70997099
method public java.lang.String getNonResourceString(int);
71007100
method public java.lang.String getPositionDescription();
@@ -16151,7 +16151,7 @@ package android.os {
1615116151

1615216152
public class Looper {
1615316153
method public void dump(android.util.Printer, java.lang.String);
16154-
method public static synchronized android.os.Looper getMainLooper();
16154+
method public static android.os.Looper getMainLooper();
1615516155
method public java.lang.Thread getThread();
1615616156
method public static void loop();
1615716157
method public static android.os.Looper myLooper();

core/java/android/content/res/TypedArray.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,20 @@ public int getDimensionPixelSize(int index, int defValue) {
469469
* {@link android.view.ViewGroup}'s layout_width and layout_height
470470
* attributes. This is only here for performance reasons; applications
471471
* should use {@link #getDimensionPixelSize}.
472-
*
472+
*
473473
* @param index Index of the attribute to retrieve.
474474
* @param name Textual name of attribute for error reporting.
475475
*
476476
* @return Attribute dimension value multiplied by the appropriate
477477
* metric and truncated to integer pixels.
478+
*
479+
* @throws RuntimeException
480+
* if this TypedArray does not contain an entry for <code>index</code>
481+
*
482+
* @deprecated Use {@link #getLayoutDimension(int, int)} instead.
483+
*
478484
*/
485+
@Deprecated
479486
public int getLayoutDimension(int index, String name) {
480487
index *= AssetManager.STYLE_NUM_ENTRIES;
481488
final int[] data = mData;

core/java/android/view/LayoutInflater.java

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.os.Handler;
2121
import android.os.Message;
2222
import android.widget.FrameLayout;
23+
import com.android.internal.R;
2324
import org.xmlpull.v1.XmlPullParser;
2425
import org.xmlpull.v1.XmlPullParserException;
2526

@@ -43,20 +44,20 @@
4344
*
4445
* <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService
4546
* (Context.LAYOUT_INFLATER_SERVICE);</pre>
46-
*
47+
*
4748
* <p>
4849
* To create a new LayoutInflater with an additional {@link Factory} for your
4950
* own views, you can use {@link #cloneInContext} to clone an existing
5051
* ViewFactory, and then call {@link #setFactory} on it to include your
5152
* Factory.
52-
*
53+
*
5354
* <p>
5455
* For performance reasons, view inflation relies heavily on pre-processing of
5556
* XML files that is done at build time. Therefore, it is not currently possible
5657
* to use LayoutInflater with an XmlPullParser over a plain XML file at runtime;
5758
* it only works with an XmlPullParser returned from a compiled resource
5859
* (R.<em>something</em> file.)
59-
*
60+
*
6061
* @see Context#getSystemService
6162
*/
6263
public abstract class LayoutInflater {
@@ -82,7 +83,7 @@ public abstract class LayoutInflater {
8283

8384
private static final HashMap<String, Constructor<? extends View>> sConstructorMap =
8485
new HashMap<String, Constructor<? extends View>>();
85-
86+
8687
private HashMap<String, Boolean> mFilterMap;
8788

8889
private static final String TAG_MERGE = "merge";
@@ -93,36 +94,36 @@ public abstract class LayoutInflater {
9394
/**
9495
* Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed
9596
* to be inflated.
96-
*
97+
*
9798
*/
9899
public interface Filter {
99100
/**
100101
* Hook to allow clients of the LayoutInflater to restrict the set of Views
101102
* that are allowed to be inflated.
102-
*
103+
*
103104
* @param clazz The class object for the View that is about to be inflated
104-
*
105+
*
105106
* @return True if this class is allowed to be inflated, or false otherwise
106107
*/
107108
@SuppressWarnings("unchecked")
108109
boolean onLoadClass(Class clazz);
109110
}
110-
111+
111112
public interface Factory {
112113
/**
113114
* Hook you can supply that is called when inflating from a LayoutInflater.
114115
* You can use this to customize the tag names available in your XML
115116
* layout files.
116-
*
117+
*
117118
* <p>
118119
* Note that it is good practice to prefix these custom names with your
119120
* package (i.e., com.coolcompany.apps) to avoid conflicts with system
120121
* names.
121-
*
122+
*
122123
* @param name Tag name to be inflated.
123124
* @param context The context the view is being created in.
124125
* @param attrs Inflation attributes as specified in XML file.
125-
*
126+
*
126127
* @return View Newly created view. Return null for the default
127128
* behavior.
128129
*/
@@ -150,14 +151,14 @@ public interface Factory2 extends Factory {
150151
private static class FactoryMerger implements Factory2 {
151152
private final Factory mF1, mF2;
152153
private final Factory2 mF12, mF22;
153-
154+
154155
FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) {
155156
mF1 = f1;
156157
mF2 = f2;
157158
mF12 = f12;
158159
mF22 = f22;
159160
}
160-
161+
161162
public View onCreateView(String name, Context context, AttributeSet attrs) {
162163
View v = mF1.onCreateView(name, context, attrs);
163164
if (v != null) return v;
@@ -172,13 +173,13 @@ public View onCreateView(View parent, String name, Context context, AttributeSet
172173
: mF2.onCreateView(name, context, attrs);
173174
}
174175
}
175-
176+
176177
/**
177178
* Create a new LayoutInflater instance associated with a particular Context.
178179
* Applications will almost always want to use
179180
* {@link Context#getSystemService Context.getSystemService()} to retrieve
180181
* the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}.
181-
*
182+
*
182183
* @param context The Context in which this LayoutInflater will create its
183184
* Views; most importantly, this supplies the theme from which the default
184185
* values for their attributes are retrieved.
@@ -191,7 +192,7 @@ protected LayoutInflater(Context context) {
191192
* Create a new LayoutInflater instance that is a copy of an existing
192193
* LayoutInflater, optionally with its Context changed. For use in
193194
* implementing {@link #cloneInContext}.
194-
*
195+
*
195196
* @param original The original LayoutInflater to copy.
196197
* @param newContext The new Context to use.
197198
*/
@@ -202,7 +203,7 @@ protected LayoutInflater(LayoutInflater original, Context newContext) {
202203
mPrivateFactory = original.mPrivateFactory;
203204
mFilter = original.mFilter;
204205
}
205-
206+
206207
/**
207208
* Obtains the LayoutInflater from the given context.
208209
*/
@@ -220,15 +221,15 @@ public static LayoutInflater from(Context context) {
220221
* pointing to a different Context than the original. This is used by
221222
* {@link ContextThemeWrapper} to create a new LayoutInflater to go along
222223
* with the new Context theme.
223-
*
224+
*
224225
* @param newContext The new Context to associate with the new LayoutInflater.
225226
* May be the same as the original Context if desired.
226-
*
227+
*
227228
* @return Returns a brand spanking new LayoutInflater object associated with
228229
* the given Context.
229230
*/
230231
public abstract LayoutInflater cloneInContext(Context newContext);
231-
232+
232233
/**
233234
* Return the context we are running in, for access to resources, class
234235
* loader, etc.
@@ -264,7 +265,7 @@ public final Factory2 getFactory2() {
264265
* called on each element name as the xml is parsed. If the factory returns
265266
* a View, that is added to the hierarchy. If it returns null, the next
266267
* factory default {@link #onCreateView} method is called.
267-
*
268+
*
268269
* <p>If you have an existing
269270
* LayoutInflater and want to add your own factory to it, use
270271
* {@link #cloneInContext} to clone the existing instance and then you
@@ -320,13 +321,13 @@ public void setPrivateFactory(Factory2 factory) {
320321
public Filter getFilter() {
321322
return mFilter;
322323
}
323-
324+
324325
/**
325326
* Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated
326327
* which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will
327328
* throw an {@link InflateException}. This filter will replace any previous filter set on this
328329
* LayoutInflater.
329-
*
330+
*
330331
* @param filter The Filter which restricts the set of Views that are allowed to be inflated.
331332
* This filter will replace any previous filter set on this LayoutInflater.
332333
*/
@@ -340,7 +341,7 @@ public void setFilter(Filter filter) {
340341
/**
341342
* Inflate a new view hierarchy from the specified xml resource. Throws
342343
* {@link InflateException} if there is an error.
343-
*
344+
*
344345
* @param resource ID for an XML layout resource to load (e.g.,
345346
* <code>R.layout.main_page</code>)
346347
* @param root Optional view to be the parent of the generated hierarchy.
@@ -360,7 +361,7 @@ public View inflate(int resource, ViewGroup root) {
360361
* reasons, view inflation relies heavily on pre-processing of XML files
361362
* that is done at build time. Therefore, it is not currently possible to
362363
* use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
363-
*
364+
*
364365
* @param parser XML dom node containing the description of the view
365366
* hierarchy.
366367
* @param root Optional view to be the parent of the generated hierarchy.
@@ -375,7 +376,7 @@ public View inflate(XmlPullParser parser, ViewGroup root) {
375376
/**
376377
* Inflate a new view hierarchy from the specified xml resource. Throws
377378
* {@link InflateException} if there is an error.
378-
*
379+
*
379380
* @param resource ID for an XML layout resource to load (e.g.,
380381
* <code>R.layout.main_page</code>)
381382
* @param root Optional view to be the parent of the generated hierarchy (if
@@ -407,7 +408,7 @@ public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
407408
* reasons, view inflation relies heavily on pre-processing of XML files
408409
* that is done at build time. Therefore, it is not currently possible to
409410
* use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
410-
*
411+
*
411412
* @param parser XML dom node containing the description of the view
412413
* hierarchy.
413414
* @param root Optional view to be the parent of the generated hierarchy (if
@@ -442,7 +443,7 @@ public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
442443
}
443444

444445
final String name = parser.getName();
445-
446+
446447
if (DEBUG) {
447448
System.out.println("**************************");
448449
System.out.println("Creating root view: "
@@ -528,17 +529,17 @@ public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
528529
* Low-level function for instantiating a view by name. This attempts to
529530
* instantiate a view class of the given <var>name</var> found in this
530531
* LayoutInflater's ClassLoader.
531-
*
532+
*
532533
* <p>
533534
* There are two things that can happen in an error case: either the
534535
* exception describing the error will be thrown, or a null will be
535536
* returned. You must deal with both possibilities -- the former will happen
536537
* the first time createView() is called for a class of a particular name,
537538
* the latter every time there-after for that class name.
538-
*
539+
*
539540
* @param name The full name of the class to be instantiated.
540541
* @param attrs The XML attributes supplied for this instance.
541-
*
542+
*
542543
* @return View The newly instantiated view, or null.
543544
*/
544545
public final View createView(String name, String prefix, AttributeSet attrs)
@@ -551,7 +552,7 @@ public final View createView(String name, String prefix, AttributeSet attrs)
551552
// Class not found in the cache, see if it's real, and try to add it
552553
clazz = mContext.getClassLoader().loadClass(
553554
prefix != null ? (prefix + name) : name).asSubclass(View.class);
554-
555+
555556
if (mFilter != null && clazz != null) {
556557
boolean allowed = mFilter.onLoadClass(clazz);
557558
if (!allowed) {
@@ -569,7 +570,7 @@ public final View createView(String name, String prefix, AttributeSet attrs)
569570
// New class -- remember whether it is allowed
570571
clazz = mContext.getClassLoader().loadClass(
571572
prefix != null ? (prefix + name) : name).asSubclass(View.class);
572-
573+
573574
boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
574575
mFilterMap.put(name, allowed);
575576
if (!allowed) {
@@ -632,10 +633,10 @@ private void failNotAllowed(String name, String prefix, AttributeSet attrs) {
632633
* given the xml element name. Override it to handle custom view objects. If
633634
* you override this in your subclass be sure to call through to
634635
* super.onCreateView(name) for names you do not recognize.
635-
*
636+
*
636637
* @param name The fully qualified class name of the View to be create.
637638
* @param attrs An AttributeSet of attributes to apply to the View.
638-
*
639+
*
639640
* @return View The View created.
640641
*/
641642
protected View onCreateView(String name, AttributeSet attrs)
@@ -679,7 +680,7 @@ View createViewFromTag(View parent, String name, AttributeSet attrs) {
679680
if (view == null && mPrivateFactory != null) {
680681
view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);
681682
}
682-
683+
683684
if (view == null) {
684685
if (-1 == name.indexOf('.')) {
685686
view = onCreateView(parent, name, attrs);
@@ -726,7 +727,7 @@ void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
726727
}
727728

728729
final String name = parser.getName();
729-
730+
730731
if (TAG_REQUEST_FOCUS.equals(name)) {
731732
parseRequestFocus(parser, parent);
732733
} else if (TAG_INCLUDE.equals(name)) {
@@ -741,7 +742,7 @@ void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
741742
final ViewGroup viewGroup = (ViewGroup) parent;
742743
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
743744
rInflate(parser, view, attrs, true);
744-
viewGroup.addView(view, params);
745+
viewGroup.addView(view, params);
745746
} else {
746747
final View view = createViewFromTag(parent, name, attrs);
747748
final ViewGroup viewGroup = (ViewGroup) parent;
@@ -810,21 +811,14 @@ private void parseInclude(XmlPullParser parser, View parent, AttributeSet attrs)
810811
// We try to load the layout params set in the <include /> tag. If
811812
// they don't exist, we will rely on the layout params set in the
812813
// included XML file.
813-
// During a layoutparams generation, a runtime exception is thrown
814-
// if either layout_width or layout_height is missing. We catch
815-
// this exception and set localParams accordingly: true means we
816-
// successfully loaded layout params from the <include /> tag,
817-
// false means we need to rely on the included layout params.
818-
ViewGroup.LayoutParams params = null;
819-
try {
820-
params = group.generateLayoutParams(attrs);
821-
} catch (RuntimeException e) {
822-
params = group.generateLayoutParams(childAttrs);
823-
} finally {
824-
if (params != null) {
825-
view.setLayoutParams(params);
826-
}
827-
}
814+
TypedArray ta = getContext().obtainStyledAttributes(attrs,
815+
R.styleable.ViewGroup_Layout);
816+
boolean definesBothWidthAndHeight =
817+
ta.hasValue(R.styleable.ViewGroup_Layout_layout_width) &&
818+
ta.hasValue(R.styleable.ViewGroup_Layout_layout_height);
819+
AttributeSet attributes = definesBothWidthAndHeight ? attrs : childAttrs;
820+
view.setLayoutParams(group.generateLayoutParams(attributes));
821+
ta.recycle();
828822

829823
// Inflate all children.
830824
rInflate(childParser, view, childAttrs, true);

core/java/android/view/ViewGroup.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5611,15 +5611,19 @@ public LayoutParams(LayoutParams source) {
56115611
}
56125612

56135613
/**
5614-
* Extracts the layout parameters from the supplied attributes.
5614+
* Extracts the <code>width</code> and <code>height</code> layout parameters
5615+
* from the supplied TypedArray, <code>a</code>, and assigns them
5616+
* to the appropriate fields. If, <code>a</code>, does not contain an
5617+
* entry for either attribute, the value, {@link ViewGroup.LayoutParams#WRAP_CONTENT},
5618+
* is used as a default.
56155619
*
56165620
* @param a the style attributes to extract the parameters from
56175621
* @param widthAttr the identifier of the width attribute
56185622
* @param heightAttr the identifier of the height attribute
56195623
*/
56205624
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
5621-
width = a.getLayoutDimension(widthAttr, "layout_width");
5622-
height = a.getLayoutDimension(heightAttr, "layout_height");
5625+
width = a.getLayoutDimension(widthAttr, WRAP_CONTENT);
5626+
height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
56235627
}
56245628

56255629
/**

0 commit comments

Comments
 (0)