Uncaught exception no application instance - blackberry

i am working on UI-application that handles multiple entry point approach.
I am referring the link and try for make a demo.
Here is the code :-
public class DemoApp extends UiApplication implements RealtimeClockListener
{
private static DemoApp dmMain ;
private static final long dm_APP_ID = 0x6ef4b845de59ecf9L;
private static DemoApp getDemoApp()
{
if(dmMain == null)
{
RuntimeStore dmAppStore = RuntimeStore.getRuntimeStore();
dmMain = (DemoApp)dmAppStore.get(dm_APP_ID);
}
return dmMain;
}
private static void setDemoApp(DemoApp demoAppMain)
{
RuntimeStore dmAppStore = RuntimeStore.getRuntimeStore();
dmAppStore.remove(dm_APP_ID);
dmAppStore.put(dm_APP_ID, demoAppMain);
}
public static void main(String[] args)
{
Log.d(" Application argument "+args);
if( args.length > 0 && args[ 0 ].equals( "Demo_Alternate" ) )
{
Log.d("Running Demo_Alternate #### Running Demo_Alternate #### Running Demo_Alternate");
dmMain = new DemoApp();
dmMain.enterEventDispatcher();
setDemoApp(dmMain);
}
else
{
Log.d("Running Demo #### Running Demo #### Running Demo #### Running Demo");
getDemoApp().initializeMain();
}
}
public DemoApp()
{
this.addRealtimeClockListener(this);
}
private void initializeMain()
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
try
{
pushScreen(new DemoMainScreen());
} catch (Exception e)
{
Log.e(e.toString());
}
}
});
}
public void clockUpdated()
{
showMessage("DemoAppClock Updated");
Log.d("DemoAppClock Updated #### DemoAppClock Updated #### DemoAppClock Updated");
}
private void showMessage(String message)
{
synchronized (Application.getEventLock())
{
Dialog dlg = new Dialog(Dialog.D_OK, message, Dialog.OK, null, Manager.FIELD_HCENTER);
Ui.getUiEngine().pushGlobalScreen(dlg, 1, UiEngine.GLOBAL_QUEUE);
}
}
}
:- I have created an alternate entry point named Demo_Alternate , that runs at start up.
:- If the application has separate entry points, that means a separate process the link
Now my questions are :-
While running the code, I am getting "Uncaught exception : no application instance".
I just want to make one application instance - don't want separate processes.
Can we use (Application) Singleton approach for alternate entry-points?

Only looked briefly at this code, but see an obvious problem here:
dmMain.enterEventDispatcher();
setDemoApp(dmMain);
enterEventDispatcher never returns, so you never put your Application instance in RuntimeStore.
I suggest you review the following KB article, you might find its approach to accessing a RuntimeStore maintained object easier to use. Or not.
Singleton using RuntimeStore
Update
If this solution does not work, please update your original post with the corrected code.

I certainly agree with Peter, that calling setDemoApp(dmMain) after enterEventDispatcher() means it doesn't get called.
That said, I think you have a more basic misunderstanding here.
Using alternate entry points will create multiple processes. See here for more.
But, you say that you don't want separate processes. Can you tell us why not?
Separate BlackBerry processes that are designed to work together can still share data, using the RuntimeStore, for example.
Maybe you could tell us more about what your "Demo" and "Demo Alternate" are supposed to do.

Related

Show DeveloperExceptionPage in production but for 'Remote Only"

I understand that the debug error page should not be seen by the end user.
However in the past, I have always been able to configure my production deployment to hide this information (so show a custom or generic error page) when called remotely, but still show the exception/stacktrace debug error, as long as I called it direct from the webserver it was hosted on.
Now looking at the latest MVC/RazorPages way, is it the case this is no longer possible, and it is either on or off, depending on the environment variable?
Before:
Within Web.Config, I use to be able to do something like:
<system.web>
<customErrors mode="RemoteOnly" </customErrors>
Now:
In Startup.cs:
I can see
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
... but I cannot see a way to allow "app.UseDeveloperExceptionPage();" when env.isDevelopement == false, but the call is local.
I am hoping I am missing something, rather than something that has now been removed.
You could possible extend DeveloperExceptionPageMiddleware, or create your own copy, using Url.IsLocalUrl to only display the error view on localhost.
I got it to work (all thanks to others on here). Hopefully it might help others to see the bits I needed, in one place.
First to address identifying if the call is local:
As for:
Url.IsLocalUrl
Supposedly it works, but is 'spoofable'. Given that it could reveal source-code/debug, the guys on this page (In ASP.NET Core how do you check if request is local?) suggest something more like:
public static class HttpContextFilters
{
public static bool IsLocalRequest(HttpContext context)
{
if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))
{
return true;
}
if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))
{
return true;
}
return false;
}
public static bool IsRemoteRequest(HttpContext context)
{
return !IsLocalRequest(context);
}
}
I can now call in Statup.cs:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseWhen(HttpContextFilters.IsLocalRequest, configuration => configuration.UseDeveloperExceptionPage());
app.UseWhen(HttpContextFilters.IsRemoteRequest, configuration => configuration.UseExceptionHandler("/Error"));
}
For an alternative solution, I suspect #Jon Galloway's approach would yield a more elegant and expandable solution...
Something along the lines of:
public class MyDeveloperExceptionPageMiddleware : Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware
{
private readonly RequestDelegate _next;
public MyDeveloperExceptionPageMiddleware(RequestDelegate next,
IOptions<DeveloperExceptionPageOptions> options,
ILoggerFactory loggerFactory,
IHostingEnvironment hostingEnvironment,
DiagnosticSource diagnosticSource) : base(next, options, loggerFactory, hostingEnvironment, diagnosticSource)
{
_next = next;
}
public async new Task Invoke(HttpContext httpContext)
{
if (HttpContextFilters.IsLocalRequest(httpContext))
{
//Show dev exceptions page
await base.Invoke(httpContext);
return;
}
await _next(httpContext);
return;
}
public static class MyDeveloperExceptionPageMiddlewareExtensions
{
public static IApplicationBuilder UseMyDeveloperExceptionPageMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyDeveloperExceptionPageMiddleware>();
}
}
Then in StartUp.cs do:
app.UseMyDeveloperExceptionPageMiddleware();
For some reason though (due to my ineptness), I couldn't quite get VS to like debugging it, but appeared to work when run from a web server. However, for what I need, and also given the fact that it would need finishing off to handle the custom error page, I think the simplified down and dirty approach above, is enough for me.

UWP Template 10 and Service Dendency Injection (MVVM) not WPF

I have spent over two weeks searching google, bing, stack overflow, and msdn docs trying to figure out how to do a proper dependency injection for a mobile app that I am developing. To be clear, I do DI every day in web apps. I do not need a crash course on what, who, and why DI is important. I know it is, and am always embracing it.
What I need to understand is how this works in a mobile app world, and in particular a UWP Template 10 Mobile app.
From my past, in a .net/Asp app I can "RegisterType(new XYZ).Singleton() blah" {please forgive syntax; just an example} in App_Start.ConfigureServices. This works almost identical in .netcore, granted some syntactic changes.
My problem is now I am trying to provide my api is going to an UWP app that needs to digest my IXYZ service. By no means do I think that they should "new" up an instance every time. There has to be a way to inject this into a container on the UWP side; and I feel I am missing something very simple in the process.
Here is the code I have:
App.xaml.cs
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// TODO: add your long-running task here
//if (args.Kind == ActivationKind.LockScreen)
//{
//}
RegisterServices();
await NavigationService.NavigateAsync(typeof(Views.SearchCompanyPage));
}
public static IServiceProvider Container { get; private set; }
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<IXYZ, XYZ>();
Container = services.BuildServiceProvider();
}
MainPage.xaml.cs:
public MainPage()
{
InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
}
MainPageViewModel:
public class MainPageViewModel : ViewModelBase
{
private readonly IXYZ _xyz;
public MainPageViewModel(IXYZ xyz)
{
//Stuff
_xyz= xyz;
}
}
I now get the error:
XAML MainPage...ViewModel type cannot be constructed. In order to be constructed in XAML, a type cannot be abstract, interface nested generic or a struct, and must have a public default constructor.
I am willing to use any brand of IoC Container, but what I need is an example of how to properly use DI for services in a UWP app. 99.9% of questions about DI is about Views (i.e. Prism?) not just a simple DI for a service (i.e. DataRepo; aka API/DataService).
Again, I feel I am missing something obvious and need a nudge in the right direction. Can somebody show me an example project, basic code, or a base flogging on how I should not be a programmer...please don't do that (I don't know if my ego could take it).
You can try to Microsoft.Hosting.Extensions just like ASP.NET, there's an implementation on Xamarin.Forms by James Montemagno, as well it can be used in UWP I have tried and it works perfectly. You have to change some parts in order to get it working.
In OnLaunched Method add Startup.Init();
public static class Startup
{
public static IServiceProvider ServiceProvider { get; set; }
public static void Init()
{
StorageFolder LocalFolder = ApplicationData.Current.LocalFolder;
var configFile = ExtractResource("Sales.Client.appsettings.json", LocalFolder.Path);
var host = new HostBuilder()
.ConfigureHostConfiguration(c =>
{
// Tell the host configuration where to file the file (this is required for Xamarin apps)
c.AddCommandLine(new string[] { $"ContentRoot={LocalFolder.Path}" });
//read in the configuration file!
c.AddJsonFile(configFile);
})
.ConfigureServices((c, x) =>
{
// Configure our local services and access the host configuration
ConfigureServices(c, x);
}).
ConfigureLogging(l => l.AddConsole(o =>
{
//setup a console logger and disable colors since they don't have any colors in VS
o.DisableColors = true;
}))
.Build();
//Save our service provider so we can use it later.
ServiceProvider = host.Services;
}
static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services)
{
//ViewModels
services.AddTransient<HomeViewModel>();
services.AddTransient<MainPageViewModel>();
}
static string ExtractResource(string filename, string location)
{
var a = Assembly.GetExecutingAssembly();
using (var resFilestream = a.GetManifestResourceStream(filename))
{
if (resFilestream != null)
{
var full = Path.Combine(location, filename);
using (var stream = File.Create(full))
{
resFilestream.CopyTo(stream);
}
}
}
return Path.Combine(location, filename);
}
}
Injecting a ViewModel is possible as well which is pretty nice.
With help from #mvermef and the SO question Dependency Injection using Template 10 I found a solutions. This turned out to be a rabbit hole where at every turn I ran into an issue.
The first problem was just getting Dependency Injection to work. Once I was able to get that figured out from the sources above I was able to start injecting my services into ViewModels and setting them to the DataContext in the code behind.
Then I ran into an injection issue problem with injecting my IXYZ services into the ViewModels of UserControls.
Pages and their ViewModels worked great but I had issues with the DataContext of the UserControl not being injected with UserControl's ViewModel. They were instead getting injected by the Page's ViewModel that held it.
The final solution turned out to be making sure that the UserControl had the DataContext being set in XAML not the code behind, as we did with the Pages, and then creating a DependencyProperty in the code behind.
To show the basic solution read below.
To make it work I started with:
APP.XAML.CS
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// long-running startup tasks go here
RegisterServices();
await Task.CompletedTask;
}
private static void RegisterServices()
{
var services = new ServiceCollection();
services.AddSingleton<IRepository, Repository>();
services.AddSingleton<IBinderService, BinderServices>();
**//ViewModels**
**////User Controls**
services.AddSingleton<AddressesControlViewModel, AddressesControlViewModel>();
services.AddSingleton<CompanyControlViewModel, CompanyControlViewModel>();
**//ViewModels**
**////Pages**
services.AddSingleton<CallListPageViewModel, CallListPageViewModel>();
services.AddSingleton<CallListResultPageViewModel, CallListResultPageViewModel>();
etc....
Container = services.BuildServiceProvider();
}
public override INavigable ResolveForPage(Page page, NavigationService navigationService)
{
**//INJECT THE VIEWMODEL FOR EACH PAGE**
**//ONLY THE PAGE NOT USERCONTROL**
if (page is CallListPage)
{
return Container.GetService<CallListPageViewModel>();
}
if (page is CallListResultPage)
{
return Container.GetService<CallListResultPageViewModel>();
}
etc...
return base.ResolveForPage(page, navigationService);
}
In the code behind for the Page
CALLLISTPAGE.XAML.CS
public CallListPage()
{
InitializeComponent();
}
CallListPageViewModel _viewModel;
public CallListPageViewModel ViewModel
{
get { return _viewModel ?? (_viewModel = (CallListPageViewModel)DataContext); }
}
In your XAML add your UserControl
CALLLISTPAGE.XAML
<binder:CompanyControl Company="{x:Bind ViewModel.SelectedCompany, Mode=TwoWay}"/>
In your UserControl make sure to add the DataContext to the XAML NOT the code behind like we did with the pages.
COMPANYCONTROL.XAML
<UserControl.DataContext>
<viewModels:CompanyControlViewModel x:Name="ViewModel" />
</UserControl.DataContext>
In the UserControl Code Behind add a Dependency Property
COMPANYCONTROL.XAML.CS
public static readonly DependencyProperty CompanyProperty = DependencyProperty.Register(
"Company", typeof(Company), typeof(CompanyControl), new PropertyMetadata(default(Company), SetCompany));
public CompanyControl()
{
InitializeComponent();
}
public Company Company
{
get => (Company) GetValue(CompanyProperty);
set => SetValue(CompanyProperty, value);
}
private static void SetCompany(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as CompanyControl;
var viewModel = control?.ViewModel;
if (viewModel != null)
viewModel.Company = (Company) e.NewValue;
}
In the end I am not sure if this is an elegant solution but it works.

How to use InputStream and OutputStream on the Event thread

I am new to blackberry development and I am creating a native blackberry application. On every screen of my application, I need to send and receive data to the server on the same connection.
What I have done so far is I have made a ConnectToServer class which has a bunch of methods for sending and receiving. I instantiate it on the main screen and I pass it to each screen as a parameter.
That class in not a thread because I only read and write when the user types in information and presses a button. So basically I am using the inputStream and outputStream on the event thread which I hear is BAD. Then I ask ConnectToServer to get me what the server sent. For instance, I get a vector which I use to make a ListField.
How can I make these UI updates?
public class Screen3 extends MainScreen {
ConnectToServer con;
Vector v;
public Screen3(String exerciseName, ConnectToServer connect)
{
con = connect;
con.send(exerciseName);
v = con.receiveVector();
mylist = new listField();
mylist.setSize(v.size());
add(mylist);
}
public void drawListRow(...)
{
graphics.drawText((String) v.elementAt(index)
}
}
So, there's many ways to approach this. First of all, since it seems like you only want one instance of ConnectToServer, and you are currently having to pass that around, you might try making that class a Singleton object. This is not necessary, and does not have anything to do with your threading problem, but I only offer it as a solution, for situations where you want to enforce that there's only one instance of something, and want to avoid having to pass it around everywhere. A simple Singleton implementation might be this:
public class ConnectToServer {
private static ConnectToServer _instance;
/** use this static method to get the one and only instance */
public static ConnectToServer getInstance() {
if (_instance == null) {
_instance = new ConnectToServer();
}
return _instance;
}
/** private to enforce Singleton pattern */
private ConnectToServer() {
}
}
And use it in your screens like this (no need to pass it into the constructor any more):
ConnectoToServer connection = ConnectToServer.getInstance();
connection.blahBlahBlah();
Now, on to the threading problem. You're right that you should not be performing network requests on the main (aka "UI", aka "Event") thread. If you have a nice separate ConnectToServer class, that makes it easier to encapsulate this behaviour. Instead of UI clients using a synchronous send() and receiveVector() method, make one method that just kicks off the request, and another callback method that the ConnectToServer class will call when the response comes back. The ConnectToServer class will use a Thread to perform this work, and thus avoid freezing the UI during the request.
I'll define an interface that the UI clients will implement:
public interface RequestListener {
/** listeners must implement this method to get data. method will be called on the UI thread */
void onDataReceived(Vector response);
}
And then the new (partial) ConnectToServer class:
public class ConnectToServer {
private Thread _worker;
private RequestListener _listener;
public void setRequestListener(RequestListener listener) {
// note: this implementation only allows one listener at once.
// make it a list if you need something more
_listener = listener;
}
/** initiate a network request on a background thread */
public void sendRequest(final String request) {
_worker = new Thread(new Runnable() {
public void run() { // run on the background/worker thread
send(request);
final Vector response = receiveVector();
if (_listener != null) {
// this assumes all our listeners are UI objects, so we pass
// data back to them on the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() { // run on UI thread
_listener.onDataReceived(response);
}
});
}
}
});
_worker.start();
}
}
Note that you should also make your original send() and receiveVector() methods in this class private. They should only be called from inside the class now, not directly from UI clients.
Then, you need to code your Screen classes like this:
public class Screen3 extends MainScreen implements RequestListener {
public Screen3(String exerciseName) {
ConnectToServer connection = ConnectToServer.getInstance();
connection.setRequestListener(this);
// kick off the request (on a background thread)
connection.sendRequest(exerciseName);
}
public void onDataReceived(Vector response) {
if (mylist == null) {
// first time data has been received, so create and add the list field:
mylist = new listField();
add(mylist);
}
mylist.setSize(response.size());
// TODO: presumably, you would copy the contents of 'response' into 'mylist' here
}
}
Also, you might also want to code the server class to protect against multiple UI clients making concurrent requests, allow current requests to be cancelled, etc. But the above should get you started on a solution that provides a responsive app, without freezing your UI.

How to remove item from ConcurrentDictionary after final ContinueWith finishes

First, could someone with 1500+ "reputation" please create a tag for "ContinueWith" (and tag this question with it)? Thanks!
Sorry for the length of this post but I don't want to waste the time of anyone trying to help me because I left out relevant details. That said, it may still happen. :)
Now the details. I am working on a service that subscribes to a couple of ActiveMQ queue topics. Two of the topics are somewhat related. One is a "company update" and one is a "product update". The "ID" for both is the CompanyID. The company topic includes the data in the product topic. Required because other subscribers need the product data but don't want/need to subscribe to the product topic. Since my service is multi-threaded (requirement beyond our discretion), as the messages arrive I add a Task to process each one in a ConcurrentDictionary using AddOrUpdate where the update parm is simply a ContinueWith (see below). Done to prevent simultaneous updates which could happen because these topics and subscribers are "durable" so if my listener service goes offline (whatever reason) we could end with multiple messages (company and/or product) for the same CompanyID.
Now, my actual question (finally!) After the Task (whether just one task, or the last in a chain of ContinueWith tasks) is finished, I want to remove it from the ConcurrentDictionary (obviously). How? I have thought of and gotten some ideas from coworkers but I don't really like any of them. I am not going to list the ideas because your answer might be one of those ideas I have but don't like but it may end up being the best one.
I have tried to compress the code snippet to prevent you from having to scroll up and down too much, unlike my description. :)
nrtq = Not Relevant To Question
public interface IMessage
{
long CompantId { get; set; }
void Process();
}
public class CompanyMessage : IMessage
{ //implementation, nrtq }
public class ProductMessage : IMessage
{ //implementation, nrtq }
public class Controller
{
private static ConcurrentDictionary<long, Task> _workers = new ConcurrentDictionary<long, Task>();
//other needed declarations, nrtq
public Controller(){//constructor stuff, nrtq }
public StartSubscribers()
{
//other code, nrtq
_companySubscriber.OnMessageReceived += HandleCompanyMsg;
_productSubscriber.OnMessageReceived += HandleProductMsg;
}
private void HandleCompanyMsg(string msg)
{
try {
//other code, nrtq
QueueItUp(new CompanyMessage(message));
} catch (Exception ex) { //other code, nrtq }
}
private void HandleProductMsg(string msg)
{
try {
//other code, nrtq
QueueItUp(new ProductMessage(message));
} catch (Exception ex) { //other code, nrtq }
}
private static void QueueItUp(IMessage message)
{
_workers.AddOrUpdate(message.CompanyId,
x => {
var task = new Task(message.Process);
task.Start();
return task;
},
(x, y) => y.ContinueWith((z) => message.Process())
);
}
Thanks!
I won't "Accept" this answer for a while because I am eager to see if anyone else can come up with a better solution.
A coworker came up with a solution which I tweaked a little bit. Yes, I am aware of the irony (?) of using the lock statement with a ConcurrentDictionary. I don't really have the time right now to see if there would be a better collection type to use. Basically, instead of just doing a ContinueWith() for existing tasks, we replace the task with itself plus another task tacked on the end using ContinueWith().
What difference does that make? Glad you asked! :) If we had just done a ContinueWith() then the !worker.Value.IsCompleted would return true as soon as the first task in the chain is completed. However, by replacing the task with two (or more) chained tasks, then as far as the collection is concerned, there is only one task and the !worker.Value.IsCompleted won't return true until all tasks in the chain are complete.
I admit I was a little concerned about replacing a task with itself+(new task) because what if the task happened to be running while it is being replaced. Well, I tested the living daylights out of this and did not run into any problems. I believe what is happening is that since task is running in its own thread and the collection is just holding a pointer to it, the running task is unaffected. By replacing it with itself+(new task) we maintain the pointer to the executing thread and get the "notification" when it is complete so that the next task can "continue" or the IsCompleted returns true.
Also, the way the "clean up" loop works, and where it is located, means that we will have "completed" tasks hanging around in the collection but only until the next time the "clean up" runs which is the next time a message is received. Again, I did a lot of testing to see if I could cause a memory problem due to this but my service never used more than 20 MB of RAM, even while processing hundreds of messages per second. We would have to receive some pretty big messages and have a lot of long running tasks for this to ever cause a problem but it is something to keep in mind as your situation may differ.
As above, in the code below, nrtq = not relevant to question.
public interface IMessage
{
long CompantId { get; set; }
void Process();
}
public class CompanyMessage : IMessage
{ //implementation, nrtq }
public class ProductMessage : IMessage
{ //implementation, nrtq }
public class Controller
{
private static ConcurrentDictionary<long, Task> _workers = new ConcurrentDictionary<long, Task>();
//other needed declarations, nrtq
public Controller(){//constructor stuff, nrtq }
public StartSubscribers()
{
//other code, nrtq
_companySubscriber.OnMessageReceived += HandleCompanyMsg;
_productSubscriber.OnMessageReceived += HandleProductMsg;
}
private void HandleCompanyMsg(string msg)
{
//other code, nrtq
QueueItUp(new CompanyMessage(message));
}
private void HandleProductMsg(string msg)
{
//other code, nrtq
QueueItUp(new ProductMessage(message));
}
private static void QueueItUp(IMessage message)
{
lock(_workers)
{
foreach (var worker in Workers)
{
if (!worker.Value.IsCompleted) continue;
Task task;
Workers.TryRemove(worker.Key, out task);
}
var id = message.CompanyId;
if (_workers.ContainsKey(id))
_workers[id] = _workers[id].ContinueWith(x => message.Process());
else
{
var task = new Task(y => message.Process(), id);
_workers.TryAdd(id, task);
task.Start();
}
}
}

Using persistence to display number of times visits for a BB Application?

I have developed an application. I want to display a message before the user starts implementing my application. Like when it is used first time i want to show "Count = 1". And when app is visited second time, "Count = 2".
How can i achieve it? I had done such thing in android using sharedperferences. But how can i do it in blackberry. I had tried something with PersistentStore. But cant achieve that, for i dont know anything about the Persistance in BB.
Also i would wish to restrict the use for 100. Is it possible?
sample codes for this will be appreciable, since i am new to this environment..
You can achieve it with Persistent Storage.
Check this nice tutorial about storing persistent data.
Also you can use SQLite. Link to a development guide which describes how to use SQLite databases in Java® applications: Storing data in SQLite databases.
You can restrict user for trying your application at most 100 times using your own logic with the help of persistent data. But I think there may be some convention, so try Google for that.
got it...
I created a new class which implements Persistable. In that class i had created an integer variable and set an getter and setter function for that integer...
import net.rim.device.api.util.Persistable;
public class Persist implements Persistable
{
private int first;
public int getCount()
{
return first;
}
public void setCount()
{
this.first += 1;
}
}
Then in the class which initializes my screen, i had declared persistence variables and 3 functions to use my Persist.java, initStore(), savePersist(), and getPersist()
public final class MyScreen extends MainScreen implements FieldChangeListener
{
/*
* Declaring my variables...
*/
private static PersistentObject store;
public Persist p;
public MyScreen()
{
//my application codes
//here uses persistence
initStore();
p = getPersist();
if(p.getCount()<100)
{
savePersist();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert(p.getCount.toString());
}
});
}
else
{
close();
System.exit(0);
}
}
//three function....
public static void initStore()
{
store = PersistentStore.getPersistentObject(0x4612d496ef1ecce8L);
}
public void savePersist()
{
synchronized (store)
{
p.setCount();
store.setContents(p);
store.commit();
}
}
public Persist getPersist()
{
Persist p = new Persist();
synchronized(store)
{
p = (Persist)store.getContents();
if(p==null)
{
p = new Persist();
}
}
return p;
}
}
I hope u all will get it right now....
If there are another simple way, plz let me know...
Thanks

Resources