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