Issue
Currently I'm working on an app that retrieves json from a server. I'm testing the app on multiple devices, but I only have one SIM card. So in order to test on a device, I need to move the SIM card to that device. If the app can't contact the server via the APN, there won't be a result.
What I did is save an instance of said json in the resources and when in debug mode, use that as the result. This way I can test everything (but the connection/request) without having to switch the SIM card every time.
private class RequestTask extends AsyncTask< String, String, String > {
...
@Override
protected void onPostExecute( String pResult ) {
...
if ( retrieveFromRawResource( pResult ) ) {
pResult = CustomUtils.parseRawResource( getActivity().getResources(), R.raw.debugjson );
}
...
}
private boolean retrieveFromRawResource( String pResult ) {
return !isValidResult( pResult ) && CustomUtils.isDebugMode( getActivity() );
}
private boolean isValidResult( String pResult ) {
return ( pResult != null && !pResult.isEmpty() );
}
...
}
public class CustomUtils {
...
public static String parseRawResource( Resources pResources, int pResourceId ) {
StringBuilder builder = new StringBuilder();
String line;
try {
InputStream is = pResources.openRawResource( pResourceId );
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
while ( ( line = reader.readLine() ) != null )
{
builder.append( line );
builder.append( "\n" );
}
return builder.toString();
} catch ( Exception e ) {
return null;
}
}
...
public static boolean isDebugMode( Context pContext ) {
return ( ( pContext.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE ) != 0 );
}
...
}
This works fine, the con to this though is the presence of the "unused" resource in the release APK. The file is quite big, so stripping it from all releases would be preferable.
Is something like this possible without having to remove/add it manually every time? Maybe using a combination of ant and Proguard? I could temporarily remove the raw json file before compiling and replace it afterwards, but the reference to that resource would still be in the code, even though it doesn't get called.
Solution
Okay, so here's what I ended up with. Since I'm already using ant, I decided to solve this in my custom_rules ant file. The trick is to override the release target, remove the debug resources, do the actual release and afterwards revert back. Since you can't completely remove the resources (they are still referenced in the code), I went with replacing them with dummy resources.
The properties file can be used to adjust the settings. In this case, all the files starting with 'debug_' in the 'res/' directory will be replaced with dummies and moved to the 'res-debug' directory.
debug.properties:
resource.files=**/debug_*
resource.dir=res/
tmp.dir=res-debug/
custom_rules.ant:
<project name="custom_rules">
<target name="remove-debug-resources">
<property file="debug.properties" prefix="debug" />
<mkdir dir="${debug.tmp.dir}" />
<!-- move all debug resources from the resources dir to the temporary debug dir -->
<move todir="${debug.tmp.dir}" overwrite="false"> <!-- don't overwrite, in case last build failed -->
<fileset dir="${debug.resource.dir}" casesensitive="yes" includes="${debug.resource.files}" />
</move>
<!-- create dummy resources for all the moved debug resources to satisfy the compiler -->
<touch>
<fileset dir="${debug.tmp.dir}" casesensitive="yes" includes="${debug.resource.files}" />
<mapper type="glob" from="*" to="${debug.resource.dir}*" />
</touch>
</target>
<target name="release" depends="remove-debug-resources, android_rules.release, restore-debug-resources" />
<target name="restore-debug-resources">
<property file="debug.properties" prefix="debug" />
<!-- move all debug resources from the temporary debug dir back to the resources dir -->
<move todir="${debug.resource.dir}" failonerror="false">
<fileset dir="${debug.tmp.dir}" casesensitive="yes" includes="${debug.resource.files}" />
</move>
<delete dir="${debug.tmp.dir}" failonerror="false" />
</target>
</project>
The most important thing to remember here is the fact that when compiling fails, the moved resources won't be restored. A simple 'ant restore-debug-resources' solves this, but you'd have to remember to do this manually. I couldn't find a clean-on-fail solution in ant.
Hope this helps others out as well!
Answered By - Roger Rapid
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.