To handle a video stream from a webcam (delivered by opencv) i am considering to use RxJava.
I am hoping to achieve the following:
being able to control the frames per second to be delivered
to be able to handle different inputs - e.g. a life webcam, a video or even a still picture
being able to switch to a picture-by-picture handling under the control of a gui
I have been experimenting a bit with RxJava but i am confused about the debounce, throttleFirst and async operators
Examples like https://stackoverflow.com/a/48723331/1497139 show some code but I am missing more detailed explanation.
Where could I find a decent example for video processing or something similar along the needs mentioned above?
The code below does some non async logic at this time - please let me know if i could build on it:
ImageFetcher
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
/**
* fetcher for Images
*
*/
public class ImageFetcher {
// OpenCV video capture
private VideoCapture capture = new VideoCapture();
private String source;
protected int frameIndex;
public int getFrameIndex() {
return frameIndex;
}
/**
* fetch from the given source
*
* #param source
* - the source to fetch from
*/
public ImageFetcher(String source) {
this.source = source;
}
/**
* try opening my source
*
* #return true if successful
*/
public boolean open() {
boolean ret = this.capture.open(source);
frameIndex=0;
return ret;
}
/**
* fetch an image Matrix
*
* #return - the image fetched
*/
public Mat fetch() {
if (!this.capture.isOpened()) {
boolean ret = this.open();
if (!ret) {
String msg = String.format(
"Trying to fetch image from unopened VideoCapture and open %s failed",
source);
throw new IllegalStateException(msg);
}
}
final Mat frame = new Mat();
this.capture.read(frame);
frameIndex++;
return !frame.empty() ? frame : null;
}
#Override
protected void finalize() throws Throwable {
super.finalize();
}
/**
* convert me to an observable
* #return a Mat emitting Observable
*/
public Observable<Mat> toObservable() {
// Resource creation.
Func0<VideoCapture> resourceFactory = () -> {
VideoCapture capture = new VideoCapture();
capture.open(source);
return capture;
};
// Convert to observable.
Func1<VideoCapture, Observable<Mat>> observableFactory = capture -> Observable
.<Mat> create(subscriber -> {
boolean hasNext = true;
while (hasNext) {
final Mat frame = this.fetch();
hasNext = frame!=null && frame.rows()>0 && frame.cols()>0;
if (hasNext) {
String msg = String.format("->%6d:%4dx%d", frameIndex, frame.cols(), frame.rows());
System.out.println(msg);
subscriber.onNext(frame);
}
}
subscriber.onCompleted();
});
// Disposal function.
Action1<VideoCapture> dispose = VideoCapture::release;
return Observable.using(resourceFactory, observableFactory, dispose);
}
}
ImageSubscriber
import org.opencv.core.Mat;
import rx.Subscriber;
public class ImageSubscriber extends Subscriber<Mat> {
public Throwable error;
public int cols = 0;
public int rows=0;
public int frameIndex=0;
public boolean completed = false;
public boolean debug = false;
#Override
public void onCompleted() {
completed = true;
}
#Override
public void onError(Throwable e) {
error = e;
}
#Override
public void onNext(Mat mat) {
cols = mat.cols();
rows = mat.rows();
frameIndex++;
if (cols==0 || rows==0)
System.err.println("invalid frame "+frameIndex);
if (debug) {
String msg = String.format("%6d:%4dx%d", frameIndex, cols, rows);
System.out.println(msg);
}
}
};
Related
I am trying to develop custom source for parallel GCS content scanning. The naive approach would be to loop through listObjects function calls:
while (...) {
Objects objects = gcsUtil.listObjects(bucket, prefix, pageToken);
pageToken = objects.getNextPageToken();
...
}
The problem is performance for the tens of millions objects.
Instead of the single thread code we can add delimiter / and submit parallel processed for each prefix found:
...
Objects objects = gcsUtil.listObjects(bucket, prefix, pageToken, "/");
for (String subPrefix : object.getPrefixes()) {
scanAsync(bucket, subPrefix);
}
...
Next idea was to try to wrap this logic in Splittable DoFn.
Choice of RestrictionTracker: I don't see how can be used any of exiting RestrictionTracker. So decided to write own. Restriction itself is basically list of prefixes to scan. tryClaim checks if there is more prefixes left and receive newly scanned to append them to current restriction. trySplit splits list of prefixes.
The problem that I faced that trySplit can be called before all subPrefixes are found. In this case current restriction may receive more work to do after it was splitted. And it seems that trySplit is being called until it returns a not null value for a given RestrictionTracker: after certain number of elements goes to the output or after 1 second via scheduler or when ProcessContext.resume() returned. This doesn't work in my case as new prefixes can be found at any time. And I can't checkpoint via return ProcessContext.resume() because if split was already done, possible work that left in current restriction will cause checkDone() function to fail.
Another problem that I suspect that I couldn't achieve parallel execution in DirectRunner. As trySplit was always called with fractionOfRemainder=0 and new RestrictionTracker was started only after current one completed its piece of work.
It would be also great to read more detailed explanation about Splittable DoFn components lifecycle. How parallel execution per element is achieved. And how and when state of RestrictionTracker can be modified.
UPD: Adding simplified code that should show intended implementation
#DoFn.BoundedPerElement
private static class ScannerDoFn extends DoFn<String, String> {
private transient GcsUtil gcsUtil;
#GetInitialRestriction
public ScannerRestriction getInitialRestriction(#Element String bucket) {
return ScannerRestriction.init(bucket);
}
#ProcessElement
public ProcessContinuation processElement(
ProcessContext c,
#Element String bucket,
RestrictionTracker<ScannerRestriction, ScannerPosition> tracker,
OutputReceiver<String> outputReceiver) {
if (gcsUtil == null) {
gcsUtil = c.getPipelineOptions().as(GcsOptions.class).getGcsUtil();
}
ScannerRestriction currentRestriction = tracker.currentRestriction();
ScannerPosition position = new ScannerPosition();
while (true) {
if (tracker.tryClaim(position)) {
if (position.completedCurrent) {
// position.clear();
// ideally I would to get checkpoint here before starting new work
return ProcessContinuation.resume();
}
try {
Objects objects = gcsUtil.listObjects(
currentRestriction.bucket,
position.currentPrefix,
position.currentPageToken,
"/");
if (objects.getItems() != null) {
for (StorageObject o : objects.getItems()) {
outputReceiver.output(o.getName());
}
}
if (objects.getPrefixes() != null) {
position.newPrefixes.addAll(objects.getPrefixes());
}
position.currentPageToken = objects.getNextPageToken();
if (position.currentPageToken == null) {
position.completedCurrent = true;
}
} catch (Throwable throwable) {
logger.error("Error during scan", throwable);
}
} else {
return ProcessContinuation.stop();
}
}
}
#NewTracker
public RestrictionTracker<ScannerRestriction, ScannerPosition> restrictionTracker(#Restriction ScannerRestriction restriction) {
return new ScannerRestrictionTracker(restriction);
}
#GetRestrictionCoder
public Coder<ScannerRestriction> getRestrictionCoder() {
return ScannerRestriction.getCoder();
}
}
public static class ScannerPosition {
private String currentPrefix;
private String currentPageToken;
private final List<String> newPrefixes;
private boolean completedCurrent;
public ScannerPosition() {
this.currentPrefix = null;
this.currentPageToken = null;
this.newPrefixes = Lists.newArrayList();
this.completedCurrent = false;
}
public void clear() {
this.currentPageToken = null;
this.currentPrefix = null;
this.completedCurrent = false;
}
}
private static class ScannerRestriction {
private final String bucket;
private final LinkedList<String> prefixes;
private ScannerRestriction(String bucket) {
this.bucket = bucket;
this.prefixes = Lists.newLinkedList();
}
public static ScannerRestriction init(String bucket) {
ScannerRestriction res = new ScannerRestriction(bucket);
res.prefixes.add("");
return res;
}
public ScannerRestriction empty() {
return new ScannerRestriction(bucket);
}
public boolean isEmpty() {
return prefixes.isEmpty();
}
public static Coder<ScannerRestriction> getCoder() {
return ScannerRestrictionCoder.INSTANCE;
}
private static class ScannerRestrictionCoder extends AtomicCoder<ScannerRestriction> {
private static final ScannerRestrictionCoder INSTANCE = new ScannerRestrictionCoder();
private final static Coder<List<String>> listCoder = ListCoder.of(StringUtf8Coder.of());
#Override
public void encode(ScannerRestriction value, OutputStream outStream) throws IOException {
NullableCoder.of(StringUtf8Coder.of()).encode(value.bucket, outStream);
listCoder.encode(value.prefixes, outStream);
}
#Override
public ScannerRestriction decode(InputStream inStream) throws IOException {
String bucket = NullableCoder.of(StringUtf8Coder.of()).decode(inStream);
List<String> prefixes = listCoder.decode(inStream);
ScannerRestriction res = new ScannerRestriction(bucket);
res.prefixes.addAll(prefixes);
return res;
}
}
}
private static class ScannerRestrictionTracker extends RestrictionTracker<ScannerRestriction, ScannerPosition> {
private ScannerRestriction restriction;
private ScannerPosition lastPosition = null;
ScannerRestrictionTracker(ScannerRestriction restriction) {
this.restriction = restriction;
}
#Override
public boolean tryClaim(ScannerPosition position) {
restriction.prefixes.addAll(position.newPrefixes);
position.newPrefixes.clear();
if (position.completedCurrent) {
// completed work for current prefix
assert lastPosition != null && lastPosition.currentPrefix.equals(position.currentPrefix);
lastPosition = null;
return true; // return true but we would need to claim again if we need to get next prefix
} else if (lastPosition != null && lastPosition.currentPrefix.equals(position.currentPrefix)) {
// proceed work for current prefix
lastPosition = position;
return true;
}
// looking for next prefix
assert position.currentPrefix == null;
assert lastPosition == null;
if (restriction.isEmpty()) {
// no work to do
return false;
}
position.currentPrefix = restriction.prefixes.poll();
lastPosition = position;
return true;
}
#Override
public ScannerRestriction currentRestriction() {
return restriction;
}
#Override
public SplitResult<ScannerRestriction> trySplit(double fractionOfRemainder) {
if (lastPosition == null && restriction.isEmpty()) {
// no work at all
return null;
}
if (lastPosition != null && restriction.isEmpty()) {
// work at the moment only at currently scanned prefix
return SplitResult.of(restriction, restriction.empty());
}
int size = restriction.prefixes.size();
int newSize = new Double(Math.round(fractionOfRemainder * size)).intValue();
if (newSize == 0) {
ScannerRestriction residual = restriction;
restriction = restriction.empty();
return SplitResult.of(restriction, residual);
}
ScannerRestriction residual = restriction.empty();
for (int i=newSize; i<=size; i++) {
residual.prefixes.add(restriction.prefixes.removeLast());
}
return SplitResult.of(restriction, residual);
}
#Override
public void checkDone() throws IllegalStateException {
if (lastPosition != null) {
throw new IllegalStateException("Called checkDone on not completed job");
}
}
#Override
public IsBounded isBounded() {
return IsBounded.UNBOUNDED;
}
}
Below I have the int indexOf(T element) method for a double linked list. I need help with the code to make sure it functions properly. The method should return the first occurence of the element in the list or -1 if element is not in the list. Below is the node class it uses. The IUDoubleLinkedList.java class implements IndexedUnsortedList.java which is where the indexOf method comes from. I tried using my indexOf method from my single linked list class but it's not the same so I hope to understand why it would be different and what code is used that is different between the the single and double linked list.
public class IUDoubleLinkedList<T> implements IndexedUnsortedList<T> {
private Node<T> head, tail;
private int size;
private int modCount;
public IUDoubleLinkedList() {
head = tail = null;
size = 0;
modCount = 0;
This is the indexOf(T element) method
#Override
public int indexOf(T element) {
// TODO Auto-generated method stub
return 0;
}
Below is the Node.java class it uses
public class Node<T> {
private Node<T> nextNode;
private T element;
private Node<T> prevNode;
/**
* Creates an empty node.
*/
public Node() {
nextNode = null;
element = null;
}
/**
* Creates a node storing the specified element.
*
* #param elem
* the element to be stored within the new node
*/
public Node(T element) {
nextNode = null;
this.element = element;
setPrevNode(null);
}
/**
* Returns the node that follows this one.
*
* #return the node that follows the current one
*/
public Node<T> getNextNode() {
return nextNode;
}
/**
* Sets the node that follows this one.
*
* #param node
* the node to be set to follow the current one
*/
public void setNextNode(Node<T> nextNode) {
this.nextNode = nextNode;
}
/**
* Returns the element stored in this node.
*
* #return the element stored in this node
*/
public T getElement() {
return element;
}
/**
* Sets the element stored in this node.
*
* #param elem
* the element to be stored in this node
*/
public void setElement(T element) {
this.element = element;
}
#Override
public String toString() {
return "Element: " + element.toString() + " Has next: " + (nextNode != null);
}
public Node<T> getPrevNode() {
return prevNode;
}
public void setPrevNode(Node<T> prevNode) {
this.prevNode = prevNode;
}
}
Check the following code, hope I helped you!
Insert item at head as well as tail end
public void insertItem(T elem) {
/* if head and tail both are null*/
if(head == null || tail == null) {
head = new Node<T>(elem);
tail = new Node<T>(elem);
}else {
Node<T> tempItem = new Node<T>();
tempItem.setElement(elem);
/* insert at head end /*
tempItem.setNextNode(head);
head.setPrevNode(tempItem);
head = tempItem;
Node<T> tempItem1 = new Node<T>();
tempItem1.setElement(elem);
/* append at tail end */
tail.setNextNode(tempItem1);
tempItem1.setPrevNode(tail);
tail = tempItem1;
}
size += 1;
}
Print item from head end
public void printItemsFromHead() {
while(head != null) {
System.out.print(head.getElement()+" --> ");
head = head.getNextNode();
}
}
Print item from tail end
public void printItemsFromTail() {
Node<T> temp = null;
while(tail != null) {
temp = tail;
System.out.print(tail.getElement()+" --> ");
tail = tail.getPrevNode();
}
/*System.out.println();
while(temp != null) {
System.out.print(temp.getElement()+" --> ");
temp = temp.getNextNode();
}*/
}
Implemention of indexOf function
#Override
public int indexOf(T element) {
int result = -1;
int headIndex = 0;
int tailIndex = size;
while(head != null && tail != null) {
if(head.getElement().equals(element)) {
result = headIndex;
break;
}
/*
if(tail.getElement().equals(element)) {
result = tailIndex;
break;
} */
head = head.getNextNode();
tail = tail.getPrevNode();
headIndex += 1;
tailIndex -= 1;
}
return result;
}
Driver class
public class Driver {
#SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void main(String[] args) {
UDoubleLinkedList uDoubleLinkedList = new UDoubleLinkedList();
uDoubleLinkedList.insertItem(1);
uDoubleLinkedList.insertItem(2);
uDoubleLinkedList.insertItem(3);
uDoubleLinkedList.insertItem(4);
uDoubleLinkedList.insertItem(5);
System.out.println(uDoubleLinkedList.indexOf(1));
}
}
I have created one application to get My location coordinates using GPS after deploying my code in simulator i am getting above error with explanation -
uncaught exception:pushmodalscreen called by a non-event thread
I am not able to figure out whats going wrong.
/**
* GPSDemo.java
*
* Copyright © 1998-2011 Research In Motion Ltd.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.gps;
import java.util.*;
import javax.microedition.location.*;
import net.rim.device.api.command.*;
import net.rim.device.api.gps.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.util.*;
import net.rim.blackberry.api.invoke.*;
import net.rim.blackberry.api.maps.*;
import net.rim.blackberry.api.menuitem.*;
/**
* This application acts as a simple travel computer, recording route
* coordinates, speed and altitude. Recording begins as soon as the
* application is invoked.
*/
public class GPSScreen extends UiApplication
{
// Represents the number of updates over which altitude is calculated, in seconds
private static final int GRADE_INTERVAL = 5;
private static final long ID = 0x5d459971bb15ae7aL;
// Represents period of the position query, in seconds
private static int _interval = 1;
private double _latitude;
private double _longitude;
private LocationProvider _locationProvider;
private GPSDemoScreen _screen;
private MapView _mapview = new MapView();
/**
* Entry point for application
*
* #param args Command line arguments (not used)
*/
public static void main(String[] args)
{
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
new GPSScreen().enterEventDispatcher();
}
/**
* Create a new GPSDemo object
*/
public GPSScreen()
{
_screen = new GPSDemoScreen();
_screen.setTitle("GPS Demo");
// Attempt to start the location listening thread
if(startLocationUpdate())
{
_screen.setState(_locationProvider.getState());
}
// Render the screen
pushScreen(_screen);
}
/**
* Invokes the Location API with Standalone criteria
*
* #return True if the <code>LocationProvider</code> was successfully started, false otherwise
*/
private boolean startLocationUpdate()
{
boolean returnValue = false;
if(!(GPSInfo.getDefaultGPSMode() == GPSInfo.GPS_MODE_NONE))
{
try
{
Criteria criteria = new Criteria();
criteria.setCostAllowed(false);
_locationProvider = LocationProvider.getInstance(criteria);
if(_locationProvider != null)
{
/*
* Only a single listener can be associated with a provider,
* and unsetting it involves the same call but with null.
* Therefore, there is no need to cache the listener
* instance request an update every second.
*/
_locationProvider.setLocationListener(new LocationListenerImpl(), _interval, -1, -1);
returnValue = true;
}
else
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Failed to obtain a location provider, exiting...");
System.exit(0);
}
});
}
}
catch(final LocationException le)
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Failed to instantiate LocationProvider object, exiting..." + le.toString());
System.exit(0);
}
});
}
}
else
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("GPS is not supported on this device, exiting...");
System.exit(0);
}
});
}
return true;
}
/**
* Implementation of the LocationListener interface. Listens for updates to
* the device location and displays the results.
*/
private class LocationListenerImpl implements LocationListener
{
/**
* #see javax.microedition.location.LocationListener#locationUpdated(LocationProvider,Location)
*/
public void locationUpdated(LocationProvider provider, Location location)
{
if(location.isValid())
{
_longitude = location.getQualifiedCoordinates().getLongitude();
_latitude = location.getQualifiedCoordinates().getLatitude();
_mapview.setZoom(Integer.parseInt("0.1"));
try
{
int latitude = (int) (100000 * _latitude);
int longitude = (int) (100000 * _longitude);
if (latitude > 9000000 || latitude < -9000000 || longitude >= 18000000 || longitude < -18000000)
{
throw new IllegalArgumentException ();
}
_mapview.setLatitude(latitude);
_mapview.setLongitude(longitude);
// Invoke BlackBerry Maps application with provided MapView object.
Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, new MapsArguments(_mapview));
}
catch(RuntimeException re)
{
// An exception is thrown when any of the following occur :
// Latitude is invalid : Valid range: [-90, 90]
// Longitude is invalid : Valid range: [-180, 180)
// Minus sign between 2 numbers.
Dialog.alert("Temporary Unavailable Service");
}
}
}
/**
* #see javax.microedition.location.LocationListener#providerStateChanged(LocationProvider, int)
*/
public void providerStateChanged(LocationProvider provider, int newState)
{
if(newState == LocationProvider.TEMPORARILY_UNAVAILABLE)
{
provider.reset();
}
_screen.setState(newState);
}
}
/**
* The main screen to display the current GPS information
*/
private final class GPSDemoScreen extends MainScreen
{
TextField _statusTextField;
/**
* Create a new GPSDemoScreen object
*/
GPSDemoScreen()
{
// Initialize UI
_statusTextField = new TextField(Field.NON_FOCUSABLE);
}
/**
* Display the state of the GPS service
*
* #param newState The state to display
*/
public void setState(final int newState)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
/**
* #see java.lang.Runnable#run()
*/
public void run()
{
switch(newState)
{
case LocationProvider.AVAILABLE:
_statusTextField.setText("Available");
break;
case LocationProvider.OUT_OF_SERVICE:
_statusTextField.setText("Out of Service");
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
_statusTextField.setText("Temporarily Unavailable");
break;
}
}
});
}
/**
* #see net.rim.device.api.ui.Screen#close()
*/
public void close()
{
if(_locationProvider != null)
{
_locationProvider.reset();
_locationProvider.setLocationListener(null, -1, -1, -1);
}
super.close();
}
}
}
I've seen that error when Dialog.alert() is used outside of the event thread. Looking at your code, I see LocationListenerImpl.locationUpdated assumes it is running on the event thread. If it is not, the UI update code would throw an exception, and then your exception handler will try to display a dialog, and that will fail as well.
I am trying to find the size of the object that I store on persistence store . I have programatically found out the size of object as shown in code but I can not find out the size of this object when it is stored on persistence store.
Does data get compressed automatically when it is comitted to store.
I m using Memory.getFlashStats().getFree(); to get the free size of persistence store before and after commitnig the object to store and the difference between the two values should be equal to the size of object that i have calculated.
please see the code
package Bean;
import java.util.Enumeration;
import java.util.Vector;
import net.rim.device.api.system.Memory;
import net.rim.device.api.system.MemoryStats;
import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.container.MainScreen;
import bean.UserCredentials;
public class MyStoreScreen extends MainScreen implements FieldChangeListener
{
private int nObjectSize;
static final long PERSISTENT_STORE_DEMO_ID = 0x42c16456ab0b5eabL;
private static PersistentObject oPersistenStore;
private int nFreePersistenceInStarting=Memory.getPersistentStats().getFree();
private int nFreePersistenceAtEnd;
ButtonField oCalculateMemButton ;
private MenuItem saveItem = new MenuItem("Save ", 110, 10)
{
public void run()
{
Dialog.alert("initially free memory ----------------------"+nFreePersistenceInStarting);
oPersistenStore = PersistentStore.getPersistentObject(PERSISTENT_STORE_DEMO_ID);
Vector storeVector = (Vector)oPersistenStore.getContents();
Vector userinfo ;
int size = (storeVector == null) ? 0 : storeVector.size();
if(size == 0)
{
userinfo = new Vector();
}
else
{
userinfo = storeVector;
}
UserCredentials oUserCredentials = new UserCredentials("akanksha","chandra",1,3434.3434,343545646);
for(int i =0;i<=100;i++)
{
userinfo.addElement(oUserCredentials);
}
nObjectSize= fnCalculateSizeOfObject(userinfo);
Dialog.alert("size of object is "+ nObjectSize);
synchronized(oPersistenStore)
{
oPersistenStore.setContents(userinfo);
oPersistenStore.commit();
}
}
};
private MenuItem getItem = new MenuItem( "Get item", 110, 11 )
{
public void run()
{
oPersistenStore = PersistentStore.getPersistentObject(PERSISTENT_STORE_DEMO_ID);
synchronized(oPersistenStore)
{
Vector arrCredential = (Vector)oPersistenStore.getContents();
if(arrCredential != null)
{
String dataContents = "";
int nSize = (arrCredential == null) ? 0 : arrCredential.size();
if(nSize != 0)
{
for (int i = 0; i < nSize; i++)
{
UserCredentials oUserCredentials = (UserCredentials)arrCredential.elementAt(i);
dataContents+="\n size of vector is "+nSize+ " username : "+oUserCredentials.getStrUsername()+"\n password : "+oUserCredentials.getStrPassword();
dataContents += "\n\nUser sal : "+oUserCredentials.getdSalary();
dataContents += "\n amount : "+oUserCredentials.getlAmount();
dataContents += "\n s no "+oUserCredentials.getnSerialNo();
}
Dialog.alert(dataContents);
}
else
{
Dialog.alert("Zero Elements ");
}
}
else
{
Dialog.alert("No contents ");
}
}
}
};
private MenuItem resetStoreItem = new MenuItem( "Delete Store", 110, 11 )
{
public void run()
{
int choice = Dialog.ask(Dialog.D_OK_CANCEL, "Do you want to delete ?");
if(choice == Dialog.D_OK)
{
// oPersistenStore = PersistentStore.getPersistentObject(PERSISTENT_STORE_DEMO_ID);
PersistentStore.destroyPersistentObject(PERSISTENT_STORE_DEMO_ID);
}
else
{
}
}
};
private MenuItem CalculateTotalFlashUsed = new MenuItem("calculate used flash size ", 0, 7)
{
public void run()
{
Dialog.alert("used size of Persistence Store is "+fnUsedPersistenceSize());
};
};
public MyStoreScreen()
{
oCalculateMemButton = new ButtonField("calculate free flash memory in starting", ButtonField.CONSUME_CLICK);
oCalculateMemButton.setChangeListener(this);
this.add(oCalculateMemButton);
this.addMenuItem(saveItem);
this.addMenuItem(getItem);
this.addMenuItem(resetStoreItem);
this.addMenuItem(CalculateTotalFlashUsed);
oPersistenStore = PersistentStore.getPersistentObject(PERSISTENT_STORE_DEMO_ID);
}
public void fieldChanged(Field field, int context)
{
if(field ==oCalculateMemButton)
{
// nFreeFlashInStarting =Memory.getFlashTotal();
// nFreeFlashInStarting =Memory.getFlashStats().getFree();
// nFreeFlashAtEnd =Memory.getFlashStats().getFree();
// String message = "total flash is Memory.getFlashStats().getAllocated(); "+nFreeFlashInStarting+" Memory.getFlashTotal() is : "+Memory.getFlashTotal();
String message = "total free flash memory in starting is :"+ nFreePersistenceInStarting;
Dialog.alert(message);
}
}
private int fnCalculateSizeOfObject(Vector userInfo )
{
int nSize = 0;
Enumeration oEnumeration = userInfo.elements();
while(oEnumeration.hasMoreElements())
{
UserCredentials oUserCredentials = (UserCredentials) oEnumeration.nextElement();
String UserName = oUserCredentials.getStrUsername();
String password = oUserCredentials.getStrPassword();
int nSerialNo = oUserCredentials.getnSerialNo();
double dSalary = oUserCredentials.getdSalary();
long lAmount = oUserCredentials.getlAmount();
nSize+= 4+8+8+fnCalculateSizeOfString(UserName)+fnCalculateSizeOfString(password);
}
return nSize;
}
private int fnCalculateSizeOfString(String strInputString)
{
//convert String to char array
char[] characterArray = strInputString.toCharArray();
int nlength = characterArray.length;
return nlength;
}
public int fnUsedPersistenceSize()
{
nFreePersistenceAtEnd = Memory.getPersistentStats().getFree();
int nUsedPersistenceMemory = nFreePersistenceInStarting -nFreePersistenceAtEnd;
return nUsedPersistenceMemory;
}
}
Memory.getFlashStats().getFree() is not that accurate, you can see it when measuring storage of the same object several times - values may be different every time.
The best way to measure object size is to calculate its fields size (what you actually doing).
I want to display a lodaing screen when user requests some http connections.I got some good samples from stackoverflow and google,But all of them displays the loading screen using a seperate screen.I want to show it in the same screen where user request for http Connection.
If any one have idea please share it to me,Thanks in advance.
I usually use a GaugeField in the status section of a MainScreen. Set it using the setStatus(Field field) method.
If your developing for OS v6.0 then RIM has provided the api for progress indication http://docs.blackberry.com/en/developers/deliverables/17971/Indicate_activity_1210002_11.jsp
For below OS v6.0 below code might help u.i.e ProgressAnimationField it is a custom field which takes the bitmap spinner/loader img, its num frames and style.
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
/**
* Custom class for spinner animation
*/
public class ProgressAnimationField extends Field implements Runnable
{
private Bitmap _bitmap;
private int _numFrames;
private int _frameWidth;
private int _frameHeight;
private int _currentFrame;
private int _timerID = -1;
private Application _application;
private boolean _visible;
public ProgressAnimationField( Bitmap bitmap, int numFrames, long style )
{
super( style | Field.NON_FOCUSABLE );
_bitmap = bitmap;
_numFrames = numFrames;
_frameWidth = _bitmap.getWidth() / _numFrames;
_frameHeight = _bitmap.getHeight();
_application = Application.getApplication();
}
public void run()
{
if( _visible ) {
invalidate();
}
}
protected void layout( int width, int height )
{
setExtent( _frameWidth, _frameHeight );
}
protected void paint( Graphics g )
{
g.drawBitmap( 0, 0, _frameWidth, _frameHeight, _bitmap, _frameWidth * _currentFrame, 0 );
_currentFrame++;
if( _currentFrame >= _numFrames ) {
_currentFrame = 0;
}
}
protected void onDisplay()
{
super.onDisplay();
_visible = true;
if( _timerID == -1 ) {
_timerID = _application.invokeLater( this, 200, true );
}
}
protected void onUndisplay()
{
super.onUndisplay();
_visible = false;
if( _timerID != -1 ) {
_application.cancelInvokeLater( _timerID );
_timerID = -1;
}
}
}