I ran into bizarre problem, hopefully you will be able to give me a hand. I start PhotoChooserTask, choose photo and when it comes back it suddenly throws an exception. Picture below depicts the situation. If I delete code connected with State or change writing object to string it works as expected. I try to find a solution why this error occurs. I'm receiving an error "rootframe_navigation_failed" and "An unhandled exception of type 'System.Runtime.Serialization.InvalidDataContractException' occurred in Microsoft.Phone.Interop.ni.dll". When PhotoChoser is invoked onNavigatedFrom is launched and then it stops, but why? Image assigning seems to be correct.
Unfortunately that has nothing in common with Image. I made simple class as I could and error still takes place but when I get rid of photochooser task and for instance put into gallery method navigation to another page there is no problem so I presume that problem results from photochoosertask. But why this happens, still trying to find out.
public partial class Page1 : PhoneApplicationPage
{
private PhotoChooserTask photo_chooser;
public Page1()
{
InitializeComponent();
}
private void gallery(object sender, RoutedEventArgs e)
{
photo_chooser = new PhotoChooserTask();
photo_chooser.Show();
photo_chooser.Completed += photo_chooser_Completed;
}
void photo_chooser_Completed(object sender, PhotoResult e)
{
switch (e.TaskResult)
{
case TaskResult.OK:
{
break;
}
}
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
PhoneApplicationService.Current.State["sth"] = new Rect();
base.OnNavigatingFrom(e);
}
}
Related
I want to update a textblock whenever there is a change in battery percent. I found the event RemainingChargePercentChanged in the Windows.Phone.Devices.Power.Battery namespace. But whenever the eventhandler is called and i try to update the textblock, i struck with error.
the error is:
An exception of type System.UnauthorizedAccessException occurred in System.Windows.ni.dll but was not handled in user code.
Do I want to select any capabilities in AppManifest file??.. If so, what?
Any help will be appreciated.
Following is my code,
public partial class MainPage : PhoneApplicationPage
{
private readonly Battery _battery;
// Constructor
public MainPage()
{
InitializeComponent();
_battery = Battery.GetDefault();
_battery.RemainingChargePercentChanged += OnRemainingChargePercentChanged;
UpdateUI();
}
private void OnRemainingChargePercentChanged(object sender, object e)
{
UpdateUI();
}
private void UpdateUI()
{
sampletext.Text = string.Format("{0} %", _battery.RemainingChargePercent);
}
}
The problem is that the event handler is called on another thread, if you read the exception message it will say Invalid cross-thread access.
The solution is to change the Text property on the UI thread using the Dispatcher, like this:
Dispatcher.BeginInvoke(() => {
sampletext.Text = string.Format("{0} %", _battery.RemainingChargePercent);
});
Edit: or your whole UpdateUI function call:
private void OnRemainingChargePercentChanged(object sender, object e)
{
Dispatcher.BeginInvoke(() => {
UpdateUI();
});
}
I am learning Swing and created a sample GUI. I am trying to achieve the following in exact order...
The user enters text into some text fields.
The user clicks a "launch" button.
The "launch" button becomes disabled.
A background thread spawns and processes the text from text fields.
the background thread finishes.
the "launch" button becomes enabled again.
I am trying to use invokeandwait as can be seen below but I get "Cannot call invokeAndWait from the event dispatcher thread". My main method is in the same .class file and I'm not too sure what exactly the "event dispatcher thread" is. Whats the best approach for something like this, do I need to setup some kind of alert in my worker thread to route back to the "event dispatcher thread"?
LaunchButton code
private void launchButtonActionPerformed(java.awt.event.ActionEvent evt) {
launchButton.setEnabled(false);
try {
java.awt.EventQueue.invokeAndWait(new MyTestThread());
} catch (Exception e) {
}
launchButton.setEnabled(true);
}
Worker Thread
public class MyTestThread extends Thread {
private int i = 0;
public void run() {
while (i < 5) {
try {
System.out.println(i++);
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Solution
Worker Thread
public class WorkerThread extends SwingWorker<Integer[], Void> {
#Override
public Integer[] doInBackground() {
System.out.println("Doing in background");
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println("Doing in background" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
public void done() {
System.out.println("Swingworker is Done");
}
}
Starting the worker thread from my Event Dispatch Thread (EDT)
new WorkerThread().execute();
The event dispatch thread (EDT) is the only thread allowed to access Swing classes and (almost all) methods. All the initizalization and events of the GUI are executed by the EDT. To execute something in the EDT you have to use SwingUtilities.invokeLater or invokeAndWait (this is equivalent to EventQueue.invokeXXX). This is why all Swing programs start with SwingUtilities.invokeLater() in the main: to execute the GUI initialization in the EDT.
While the EDT is busy the UI freezes that's why background threads are useful. When you need to do a big amount of work independent from the UI (calculations, I/O, transmission, ...) you have to use "worker threads".
For more about threading in Swing see this tutorial: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/
Now, what you are trying to accomplish is right but the tools you are using aren't.
You need to know two things: how to handle events (like button presses) and how to create background threads.
For the first one see this tutorial:
http://docs.oracle.com/javase/tutorial/uiswing/components/button.html
You just need to add anActionListener to a button and whenever the button throws an event the listener's actionPerformed method will be executed, in the EDT.
Minimal example:
JButton button = new JButton("Test button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("The button was pressed.");
}
}
The event variable contains useful information, for example event.getSource() return the object that threw the event, in this case the button.
Now what you want to do when the button is pressed is create a worker thread. Worker threads are created using the SwingWorker class, as you've seen in the concurrency tutorial. There you can define a piece of code that will be executed in the background thread (in the doInBackground() method) and a piece of code that will be executed in the EDT after the work in the background is done (in the done() method).
So you'd want to do something like this:
private static JButton _button;
//...
_button = new JButton("Test button");
_button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("The button was pressed.");
_button.setEnabled(false);
SwingWorker worker = new SwingWorker()
{
#Override
protected Object doInBackground() throws Exception
{
//do something useful in the background thread
return null;
}
#Override
protected void done()
{
_button.setEnabled(true);
}
}
worker.execute();
}
}
There's a lot of information out there about this. Read the Java reference for the classes, read the official tutorials and search in SO. Another good tutorial about SwingWorkers is: http://www.javacreed.com/swing-worker-example/
I am working on a Windows Phone 8 App which should be protected with a passcode. What is the best way to show the passcode screen everytime the app is lauchend or activated?
I think the central point of action shoule be the App.xaml.cs with its Launch and Activation event handlers. But how exactly can I show the passcode screen?
The problem is, that one never know which pages will be displayed when the app launches or is reactivated. It is either the main page or any other page which was last displayed when the app was deactivated.
I tried to intercept the navigation to the first page, cancel it and show the passcode page instead:
// App.xaml.cs
private void InitializePhoneApplication() {
...
RootFrame.Navigating += HandleFirstNavigation;
...
}
private void HandleFirstNavigation(object sender, NavigatingCancelEventArgs e) {
RootFrame.Navigating -= HandleFirstNavigation;
e.Cancel = true;
RootFrame.Dispatcher.BeginInvoke(new Action(this.OpenPasscodePage));
}
private void OpenPasscodePage() {
RootFrame.Navigate(PasscodePageUri);
}
This works, but only when the app lauchend. When the app reactivated (dormant or tombstoned) the e.Cancel is irgnored. Although the navigation to the passcode page is called the original page is shown.
Moving the navigation the the passcode page from Navigating to Navigated does not worth either:
private void InitializePhoneApplication() {
...
RootFrame.Navigated += PasscodePageAfterFirstNavigation;
...
}
private void PasscodePageAfterFirstNavigation(object sender, EventArgs e) {
RootFrame.Navigated-= PasscodePageAfterFirstNavigation;
RootFrame.Navigate(PasscodePageUri);
}
This seems to be some kind of race condition: Sometimes the passcode page is shown, sometimes the original page. Even if the passcode pages comes up this looks bad because one first see the original page for the fraction of a second before the app navigates further to the passcode page.
Both solution do not work. Any idea what is the right way to implement this?
EDIT: Meanwhile I tried a third solution which does not work either. This solution uses the Uri Mapper:
App.xaml.cs
public bool PasscodeWasConfirmed; private void Application_Launching(object sender, LaunchingEventArgs e) {
...
PasscodeWasConfirmed = false;
...
}
private void Application_Activated(object sender, ActivatedEventArgs e) {
...
PasscodeWasConfirmed = false;
...
}
public Uri InitialPageUri;
public bool ShouldRedirectToPasscodePage(Uri uri) {
if (PasswordWasConfirmend == false) {
InitialPageUri = uri;
return true;
}
return false;
}
UriMapper
public class AppUriMapper : UriMapperBase {
public override Uri MapUri(Uri uri) {
App app = (Application.Current as App);
if (app != null) {
if (app.ShouldRedirectToPasscodePage(uri))
return PasscodeQueryPage.PageUri;
}
// default
return uri;
}
}
PasscodePage
public partial class PasscodePage : PhoneApplicationPage {
...
private void PasscodeConfirmed() {
App app = (Application.Current as App);
app.PasscodeWasConfirmed = true;
NavigationService.Navigate(app.InitialPageUri);
}
}
The Logic is working without any problem, but the app does not navigate to InitialPageUri after the passcode was confirmed. The Uri Mapper is called and correctly and returns the InitialPageUri (no redirect any more). But no navigation happens...
There are no errors, exceptions or debug output. simply nothing happes...
Biggest problem when using Uri Mapper:
When the app is reactivated from Dormant state there is no navigation which could be mapped or redirected...
(I've edited previous answer instead of adding a new one)
I've spend a little time trying to find a solution, and I don't see why your code doesn't run.
In my case it's enough if I do such a change in App.xaml:
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
App.RootFrame.Navigate(new Uri("/passPage.xaml", UriKind.RelativeOrAbsolute));
}
This works on my example which is under the link http://sdrv.ms/1ajH40E
But - I cannot prevent user from seeing last screen when he holds back buton and is chosing to which app return, and then for a blink he can see the last page before leaving the app. I don't know if it is possible to change this behaviour after clicking MS Button:
windows phone change deactivated app image
Second edit
Ok - maybe I've found solution why it sometiems work and sometimes not in your code. After pressing the Start or Search buton the App can go to two cases: Tombstone and non-tombsone. After return different events happen. Code above works with Tombstone case but not with non-tombstone. To work it with the second you need to add (because page is not initialized again) - (of course it can be different solution):
bool afterActivation = false;
private void Application_Activated(object sender, ActivatedEventArgs e)
{
afterActivation = true;
}
private void CheckForResetNavigation(object sender, NavigationEventArgs e)
{
// If the app has received a 'reset' navigation, then we need to check
// on the next navigation to see if the page stack should be reset
if (e.NavigationMode == NavigationMode.Reset)
RootFrame.Navigated += ClearBackStackAfterReset;
if (afterActivation)
{
afterActivation = false;
App.RootFrame.Navigate(new Uri("/passPage.xaml", UriKind.RelativeOrAbsolute));
}
}
Please also ensure of your debug properties in VS: Project->Properties->Debug->Tombstone upon deactiovation checkbox.
You can also find some information here (if you haven't seen it before):
http://blogs.msdn.com/b/ptorr/archive/2010/12/11/how-to-correctly-handle-application-deactivation-and-reactivation.aspx
I have a JNI function that can take a while to complete, and I want a JProgress bar in indeterminate mode running while it is finishing the function. I have read the tutorials provided by Oracle, but the nature of their tutorials doesn't seem to help me understand how to do it. I realize that I should be running this function in a background thread, but I'm not quite sure how to do it.
Here is relevant code. I have a button (runButton) that will call the function, mainCpp(), when pressed:
public class Foo extends javax.swing.JFrame
implements ActionListener,
PropertyChangeListener{
#Override
public void actionPerformed(ActionEvent ae){
//Don't know what goes here, I don't think it is necessary though because I do not intend to use a determinate progress bar
}
#Override
public void propertyChange(PropertyChangeEvent pce){
//I don't intend on using an determinate progress bar, so I also do not think this is necassary
}
class Task extends SwingWorker<Void, Void>{
#Override
public Void doInBackground{
Foo t = new Foo();
t.mainCpp();
System.out.println("Done...");
}
return null;
}
/*JNI Function Declaration*/
public native int mainCpp(); //The original function takes arguments, but I have ommitted them for simplicity. If they are part of the problem, I can put them back in.
...//some codes about GUI
private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {
ProgressBar.setIndeterminate(true);
Task task = new Task();
task.execute();
ProgressBar.setIndeterminate(false);
}
/*Declarations*/
private javax.swing.JButton runButton;
}
Any help would be appreciated.
EDIT: Editted in an attempt to do what kiheru suggested, but still does not work.
Assuming you have a SwingWorker like this:
class Task extends SwingWorker<Void, Void>{
#Override
public Void doInBackground() {
// I'm not sure of the code snippets if you are already in a
// Foo instance; if this is internal to Foo then you obviously do
// not need to create another instance, but just call mainCpp().
Foo t = new Foo();
t.mainCpp();
return null;
}
#Override
public void done()
// Stop progress bar, etc
...
}
}
You can either keep an instance in a field of the containing object, and then using it would work like this:
private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {
// Start progress bar, disable the button, etc.
...
// Task task has been created earlier, maybe in the constructor
task.execute();
}
, or you can create a worker in place:
private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {
// Start progress bar, disable the button, etc.
...
new Task().execute();
}
Basically I need the opposite behaviour of the #Test(timeout=X) annotation.
The problem I want to solve is to detect in some way that the method never ends (as a right behaviour). I am assuming that if the method didn't stop after X seconds, I am sure "it will never end".
Thanks!
You could try this:
#Test
public void methodDoesNotReturnFor5Seconds() throws Exception {
Thread t = new Thread(new Runnable() {
public void run() {
methodUnderTest();
}
});
t.start();
t.join(5000);
assertTrue(t.isAlive());
// possibly do something to shut down methodUnderTest
}