I'm not really sure if this is right, so it would be great to have it reviewed.
I'm creating an Android library and made a final class with completely static methods for getting internal resources (res, layout, etc.) since there are conflicts with the host application when using the R
class for imported libraries. However, I'm not so sure if I'm in the right path, since I've always read that static classes are a code smell, despite being convinced by some StackOverflow answers. There's also an issue with unit tests since PowerMock cannot be run with some frameworks such as Espresso.
public final class ResourceUtils {
private static final String TAG = ResourceUtils.class.getSimpleName();
private ResourceUtils() {}
/**
* <p>Retrieves the id of a resource.</p>
* <p>Equivalent to R.[resourceType].[name]</p>
* @param context
* @param name the name of the resource
* @param resourceType the resourceType (see ResourceType enum)
* @return id of the resource
*/
public static int getResourceId(Context context, String name, ResourceType resourceType) {
if (context == null || name == null) {
return 0;
}
return context.getResources().getIdentifier(name, resourceType.toString(), context.getPackageName());
}
/**
* <p>Retrieves the content of a raw resource file.</p>
* @param context
* @param filename the name (excluding the file extension) of the raw file under res/raw
* @return CharSequence representation of the content of the raw resource
*/
public static CharSequence readRawResource(Context context, String filename) {
if (context == null || filename == null) {
return null;
}
int rawId = getResourceId(context, filename, ResourceType.RAW);
if (rawId == 0) {
return null;
}
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(rawId)));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
reader.close();
} catch (IOException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return writer.toString();
}
public enum ResourceType {
COLOR("color"),
DIMENSION("dimen"),
DRAWABLE("drawable"),
INTEGER("integer"),
LAYOUT("layout"),
RAW("raw"),
STRING("string"),
STYLE("style"),
VIEW("id")
;
private final String text;
/**
* @param text
*/
private ResourceType(final String text) {
this.text = text;
}
/* (non-Javadoc)
* @see java.lang.Enum#toString()
*/
@Override
public String toString() {
return text;
}
}
}
Here's a sample usage for getResourceId
:
Actual:
public class SomeActivity {
...
setContentView(ResourceUtils.getResourceId(this, "activity_some", ResourceUtils.ResourceType.LAYOUT));
...
}
R
class usage equivalent:
public class SomeActivity {
...
setContentView(R.layout.activity_some);
...
}
For readRawResource
, let's say there's a raw resource named raw.txt
, calling ResourceUtils.readRawResource
will return the contents of the text file as a string.