ComponentName.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.content; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21 22/** 23 * Identifier for a specific application component 24 * ({@link android.app.Activity}, {@link android.app.Service}, 25 * {@link android.content.BroadcastReceiver}, or 26 * {@link android.content.ContentProvider}) that is available. Two 27 * pieces of information, encapsulated here, are required to identify 28 * a component: the package (a String) it exists in, and the class (a String) 29 * name inside of that package. 30 * 31 */ 32public final class ComponentName implements Parcelable { 33 private final String mPackage; 34 private final String mClass; 35 36 /** 37 * Create a new component identifier. 38 * 39 * @param pkg The name of the package that the component exists in. Can 40 * not be null. 41 * @param cls The name of the class inside of <var>pkg</var> that 42 * implements the component. Can not be null. 43 */ 44 public ComponentName(String pkg, String cls) { 45 if (pkg == null) throw new NullPointerException("package name is null"); 46 if (cls == null) throw new NullPointerException("class name is null"); 47 mPackage = pkg; 48 mClass = cls; 49 } 50 51 /** 52 * Create a new component identifier from a Context and class name. 53 * 54 * @param pkg A Context for the package implementing the component, 55 * from which the actual package name will be retrieved. 56 * @param cls The name of the class inside of <var>pkg</var> that 57 * implements the component. 58 */ 59 public ComponentName(Context pkg, String cls) { 60 if (cls == null) throw new NullPointerException("class name is null"); 61 mPackage = pkg.getPackageName(); 62 mClass = cls; 63 } 64 65 /** 66 * Create a new component identifier from a Context and Class object. 67 * 68 * @param pkg A Context for the package implementing the component, from 69 * which the actual package name will be retrieved. 70 * @param cls The Class object of the desired component, from which the 71 * actual class name will be retrieved. 72 */ 73 public ComponentName(Context pkg, Class<?> cls) { 74 mPackage = pkg.getPackageName(); 75 mClass = cls.getName(); 76 } 77 78 /** 79 * Return the package name of this component. 80 */ 81 public String getPackageName() { 82 return mPackage; 83 } 84 85 /** 86 * Return the class name of this component. 87 */ 88 public String getClassName() { 89 return mClass; 90 } 91 92 /** 93 * Return the class name, either fully qualified or in a shortened form 94 * (with a leading '.') if it is a suffix of the package. 95 */ 96 public String getShortClassName() { 97 if (mClass.startsWith(mPackage)) { 98 int PN = mPackage.length(); 99 int CN = mClass.length(); 100 if (CN > PN && mClass.charAt(PN) == '.') { 101 return mClass.substring(PN, CN); 102 } 103 } 104 return mClass; 105 } 106 107 /** 108 * Return a String that unambiguously describes both the package and 109 * class names contained in the ComponentName. You can later recover 110 * the ComponentName from this string through 111 * {@link #unflattenFromString(String)}. 112 * 113 * @return Returns a new String holding the package and class names. This 114 * is represented as the package name, concatenated with a '/' and then the 115 * class name. 116 * 117 * @see #unflattenFromString(String) 118 */ 119 public String flattenToString() { 120 return mPackage + "/" + mClass; 121 } 122 123 /** 124 * The samee as {@link #flattenToString()}, but abbreviates the class 125 * name if it is a suffix of the package. The result can still be used 126 * with {@link #unflattenFromString(String)}. 127 * 128 * @return Returns a new String holding the package and class names. This 129 * is represented as the package name, concatenated with a '/' and then the 130 * class name. 131 * 132 * @see #unflattenFromString(String) 133 */ 134 public String flattenToShortString() { 135 return mPackage + "/" + getShortClassName(); 136 } 137 138 /** 139 * Recover a ComponentName from a String that was previously created with 140 * {@link #flattenToString()}. It splits the string at the first '/', 141 * taking the part before as the package name and the part after as the 142 * class name. As a special convenience (to use, for example, when 143 * parsing component names on the command line), if the '/' is immediately 144 * followed by a '.' then the final class name will be the concatenation 145 * of the package name with the string following the '/'. Thus 146 * "com.foo/.Blah" becomes package="com.foo" class="com.foo.Blah". 147 * 148 * @param str The String that was returned by flattenToString(). 149 * @return Returns a new ComponentName containing the package and class 150 * names that were encoded in <var>str</var> 151 * 152 * @see #flattenToString() 153 */ 154 public static ComponentName unflattenFromString(String str) { 155 int sep = str.indexOf('/'); 156 if (sep < 0 || (sep+1) >= str.length()) { 157 return null; 158 } 159 String pkg = str.substring(0, sep); 160 String cls = str.substring(sep+1); 161 if (cls.length() > 0 && cls.charAt(0) == '.') { 162 cls = pkg + cls; 163 } 164 return new ComponentName(pkg, cls); 165 } 166 167 /** 168 * Return string representation of this class without the class's name 169 * as a prefix. 170 */ 171 public String toShortString() { 172 return "{" + mPackage + "/" + mClass + "}"; 173 } 174 175 @Override 176 public String toString() { 177 return "ComponentInfo{" + mPackage + "/" + mClass + "}"; 178 } 179 180 @Override 181 public boolean equals(Object obj) { 182 try { 183 if (obj != null) { 184 ComponentName other = (ComponentName)obj; 185 // Note: no null checks, because mPackage and mClass can 186 // never be null. 187 return mPackage.equals(other.mPackage) 188 && mClass.equals(other.mClass); 189 } 190 } catch (ClassCastException e) { 191 } 192 return false; 193 } 194 195 @Override 196 public int hashCode() { 197 return mPackage.hashCode() + mClass.hashCode(); 198 } 199 200 public int describeContents() { 201 return 0; 202 } 203 204 public void writeToParcel(Parcel out, int flags) { 205 out.writeString(mPackage); 206 out.writeString(mClass); 207 } 208 209 /** 210 * Write a ComponentName to a Parcel, handling null pointers. Must be 211 * read with {@link #readFromParcel(Parcel)}. 212 * 213 * @param c The ComponentName to be written. 214 * @param out The Parcel in which the ComponentName will be placed. 215 * 216 * @see #readFromParcel(Parcel) 217 */ 218 public static void writeToParcel(ComponentName c, Parcel out) { 219 if (c != null) { 220 c.writeToParcel(out, 0); 221 } else { 222 out.writeString(null); 223 } 224 } 225 226 /** 227 * Read a ComponentName from a Parcel that was previously written 228 * with {@link #writeToParcel(ComponentName, Parcel)}, returning either 229 * a null or new object as appropriate. 230 * 231 * @param in The Parcel from which to read the ComponentName 232 * @return Returns a new ComponentName matching the previously written 233 * object, or null if a null had been written. 234 * 235 * @see #writeToParcel(ComponentName, Parcel) 236 */ 237 public static ComponentName readFromParcel(Parcel in) { 238 String pkg = in.readString(); 239 return pkg != null ? new ComponentName(pkg, in) : null; 240 } 241 242 public static final Parcelable.Creator<ComponentName> CREATOR 243 = new Parcelable.Creator<ComponentName>() { 244 public ComponentName createFromParcel(Parcel in) { 245 return new ComponentName(in); 246 } 247 248 public ComponentName[] newArray(int size) { 249 return new ComponentName[size]; 250 } 251 }; 252 253 /** 254 * Instantiate a new ComponentName from the data in a Parcel that was 255 * previously written with {@link #writeToParcel(Parcel, int)}. Note that you 256 * must not use this with data written by 257 * {@link #writeToParcel(ComponentName, Parcel)} since it is not possible 258 * to handle a null ComponentObject here. 259 * 260 * @param in The Parcel containing the previously written ComponentName, 261 * positioned at the location in the buffer where it was written. 262 */ 263 public ComponentName(Parcel in) { 264 mPackage = in.readString(); 265 if (mPackage == null) throw new NullPointerException( 266 "package name is null"); 267 mClass = in.readString(); 268 if (mClass == null) throw new NullPointerException( 269 "class name is null"); 270 } 271 272 private ComponentName(String pkg, Parcel in) { 273 mPackage = pkg; 274 mClass = in.readString(); 275 } 276} 277