I'm looking for one way to share a non-parcelable item from my application and my current Service. This is the situation:
I have a Service to store all the media data from a camera application, photos, videos etc. The mission of this service is continue saving the media when the user go to background. When I did this in a first instance, I had a lot of SIGSEGV errors:
08-22 10:15:49.377 15784-15818/com.bq.camerabq A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x8c3f4000 in tid 15818 (CameraModuleBac)
This was because the Image item that I recover from my imageReaders are not parceable, I fix this saving the Bytebuffers from the image instead of the whole image item.
But, now I'm getting the same problem with DNG captures, because from my imageReader I got a CaptureResult item that I need to use to create a DngCreator
item to write the dng image.
CaptureResults and DngCreators are not parcelables or Serializables, so I don't find a way to save my data from the application to recover it in the service if I'm in background.
I have tried to copy the reference when calling the Service and it didn't worked. Also I saw in other posts as Object Sharing Between Activities in Android and Object Sharing Between Activities in Android that I can save the item in a static reference in my application context to be able to recover it in different activities. So finally I tried this:
public class DngManager extends Application {
public static DngManager sDngManagerInstance;
protected Hashtable<String, CaptureResult> dngCaptureResults;
private static String DNG_KEY_PREFIX = "dngResult_";
public DngManager(){
super();
createDNGCaptureResults();
}
public void createDNGCaptureResults() {
dngCaptureResults = new Hashtable<String, CaptureResult>();
}
public boolean addDNGCaptureResultToSharedMem(long dateKey, CaptureResult value) {
dngCaptureResults.put(DNG_KEY_PREFIX + dateKey, value);
return true;
}
public CaptureResult getFromDNGCaptureResults(long dateKey) {
return dngCaptureResults.get(DNG_KEY_PREFIX + dateKey);
}
private boolean containsDNGCaptureResults(long dateKey) {
return dngCaptureResults.containsKey(DNG_KEY_PREFIX + dateKey);
}
public void clearDNGCaptureResults(long dateKey) {
String partKey = String.valueOf(dateKey);
Enumeration<String> e2 = dngCaptureResults.keys();
while (e2.hasMoreElements()) {
String i = (String) e2.nextElement();
if (i.contains(partKey))
dngCaptureResults.remove(i);
}
}
public static DngManager getInstance(){
if (sDngManagerInstance == null){
sDngManagerInstance = new DngManager();
}
return sDngManagerInstance;
}
}
And later I recover it in my service:
CaptureResult dngResult = ((DngManager)getApplication()).getFromDNGCaptureResults(mDngPicture.getDateTaken());
if (dngResult == null) {
return;
}
DngCreator dngCreator = new DngCreator(mCameraCharacteristics, dngResult);
path = Storage.generateFilepath(title, "dng");
file = new File(Uri.decode(path));
try {
Log.e(TAG, "[DngSaveTask|run] WriteByteBuffer: Height " + mDngPicture.getSize().getHeight() + " Width " + mDngPicture.getSize().getWidth());
OutputStream os = new FileOutputStream(file);
dngCreator.writeByteBuffer(os, mDngPicture.getSize(), mDngPicture.getDngByteBuffer(), 0);
} catch (IOException e) {
Log.d(TAG, "[DngSaveTask|run] " + e);
e.printStackTrace();
}
dngCreator.close();
Log.e(TAG, "[DngSaveTask|run] Cleaning Result from shared memory");
DngManager.getInstance().clearDNGCaptureResults(mDngPicture.getDateTaken());
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{file.getAbsolutePath()}, null, null);
Anyway, it still giving me back a SIGSEGV error. What else can I try?